sdcard에 저장된 이미지가 Android의 갤러리 앱에 표시되지 않습니다.


93

이미지를 sdcard에 저장했는데 sdcard를 꺼내서 다시 돌려 줄 때까지 갤러리 애플리케이션에 표시되지 않습니다.

왜 그런지 아십니까?

갤러리 애플리케이션에 파일 저장시 업데이트되지 않는 캐시가있는 것 같습니다.

사실, 나는 또한 갤러리 응용 프로그램에서 방금 저장 한 이미지를 열 것을 아무 성공이 없다 할
이 문제에 대한 내 질문입니다.


1
이 질문은이 튜토리얼에서 단계적으로 답변되었습니다 : stackoverflow.com/questions/30506301/…
Takermania

답변:


45

시스템은 새 이미지 (및 기타) 파일을 찾기 위해 마운트 될 때 SD 카드를 스캔합니다. 프로그래밍 방식으로 파일을 추가하는 경우 다음 클래스를 사용할 수 있습니다.

http://developer.android.com/reference/android/media/MediaScannerConnection.html


4
참고 : 질문이 파일 추가에 관한 것이지만 MediaScannerConnection은 파일 삭제에 대한 솔루션을 제공하지 않습니다. 삭제 된 파일의 상위 폴더를 검색하도록 요청하는 경우에도 마찬가지입니다.
AlikElzin-kilaka

86

더 간단한 해결책은 정적 편의 메서드 scanFile () 을 사용하는 것입니다 .

File imageFile = ...
MediaScannerConnection.scanFile(this, new String[] { imageFile.getPath() }, new String[] { "image/jpeg" }, null);

this당신의 활동은 어디에 있든 (또는 어떤 컨텍스트 든), mime-type은 비표준 파일 확장자를 사용하고있는 경우에만 필요하고 null는 선택적 콜백을위한 것입니다 (이런 간단한 경우에는 필요하지 않습니다).


2
다른 사람 (및 Google)이 제공하는 브로드 캐스트 방법 인 Spot on은 거의 작동하지 않습니다.
Chris.Jenkins 2013

2
이것은 이전 안드로이드 버전 ~ 4.0에서 나를 위해 일했지만 지금은 4.3 이상에서 작동하지 않는 것 같습니다. 이미지가 갤러리 앱에 표시되지 않습니다.
hooby3dfx

완벽 해! 다음으로 컨텍스트를 얻을 수 있습니다. Android.App.Application.Context
jug

마시 멜로에 근무
Hitesh Sahu

66

원래 질문 및이 문제가있을 수있는 다른 사람에 대한 나의 대답 :

나는 사람들이 SD 카드에 저장 한 내 앱의 이미지가 갤러리에 즉시 표시되지 않는 동일한 문제가 발생했습니다. 몇 가지 검색 후 문제를 해결 한 'sdcard에 저장'코드 뒤에 삽입 된 코드 한 줄을 발견했습니다.

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

이 방송을 사용하려면 미디어 스캐너를 사용해야합니까? 내 갤러리에 이미지를 표시하는 다른 방법을 사용하고 있습니다. 위의 sendBroadcast를 저장 버튼을 클릭하면 내 갤러리가 새 이미지로 업데이트되지 않습니다!
변경

4
오래되었지만 도움이 될 수 있습니다.보다 구체적인 경로 : sendBroadcast (new Intent (Intent.ACTION_MEDIA_MOUNTED, Uri.parse ( "file : //"+ Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_PICTURES)))); 이 방법 (이 답변, 내 의견뿐만 아니라)은 에뮬레이터에서 작동하지 않습니다. 실제 장치에서 테스트하십시오.

나는 받아 들여지는 대답이 올바른 방법을 제공한다고 생각합니다. 그러나 API <= 7을 지원하려는 경우 이것은 좋은 대안입니다.
Amr Mostafa 2013

귀하의 답변은 다른 장치에 유용합니다. 내 응용 프로그램 폴더를 스캔하려고 할 때 HTC에서 작동하지 않습니다. 새로 추가 된 이미지가 표시되지 않습니다.
MobileEvangelist 2013

6
이것은 Android 4.4 이상에서 더 이상 지원되지 않는 것 같습니다. 이 경우 권한 예외가 발생합니다.
rsp1984 2014 년

13

의도에 따라 이미지를 미디어 갤러리에 추가 할 수도 있습니다. 예제 코드를 살펴보고 어떻게 수행되는지 확인하세요.

ContentValues image = new ContentValues();

image.put(Images.Media.TITLE, imageTitle);
image.put(Images.Media.DISPLAY_NAME, imageDisplayName);
image.put(Images.Media.DESCRIPTION, imageDescription);
image.put(Images.Media.DATE_ADDED, dateTaken);
image.put(Images.Media.DATE_TAKEN, dateTaken);
image.put(Images.Media.DATE_MODIFIED, dateTaken);
image.put(Images.Media.MIME_TYPE, "image/png");
image.put(Images.Media.ORIENTATION, 0);

 File parent = imageFile.getParentFile();
 String path = parent.toString().toLowerCase();
 String name = parent.getName().toLowerCase();
 image.put(Images.ImageColumns.BUCKET_ID, path.hashCode());
 image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
 image.put(Images.Media.SIZE, imageFile.length());

 image.put(Images.Media.DATA, imageFile.getAbsolutePath());

 Uri result = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);

안녕하세요. 이 방법은 MediaStore에 이미지를 추가합니다. 반환 Uri된 이미지 를 확인하여 확인 했지만 삽입 된 이미지가 갤러리에 표시되지 않는 것이 문제입니다. 나는 갤러리의 시작과 끝에서 모두 확인했습니다. 삽입 된 이미지가 갤러리에 즉시 표시되도록 방법을 제안 해 주시겠습니까?
Shajeel Afzal 2015

12

Android KITKAT을 포함한 갤러리 새로 고침

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
}
else
{
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}

첫 번째 조건 whitin "IF"문 안에있는 코드는 KitKat (Android 4.4.4, API 19)에서 잘 작동합니다.
Alex

8

MediaScannerConnection에 대한 코드는 다음과 같습니다.

MyMediaConnectorClient client = new MyMediaConnectorClient(newfile);
MediaScannerConnection scanner = new MediaScannerConnection(context, client);
client.setScanner(scanner);
scanner.connect();

newfile은 새 / 저장된 파일의 파일 개체입니다.


2
답변 주셔서 감사합니다. 사실이 프로젝트는 이미 오래전에 끝 냈는데 ... 제가 사용한 솔루션이 뭔지도 기억 나지 않습니다. 당신은 또한의 구현을 제공하려는 경우 다른 사용자가 도움이 솔루션을 찾을 수있는 MyMediaConnectorClient...
마이클 케슬 러

예-지금이 문제로 인해 정말 두통이 있습니다. 게시 해주세요 :)
Steve

예, 흐름이 어떻게되어야하는지 잘 모르겠습니다.-내가 틀린 부분을 수정합니다. MediaScannerConnection을 사용하여 SDCAARD 정보를 업데이트 할 수 있으므로 카메라로 사진을 찍고 새 파일을 MSC로 전달하면 이제 파일에 액세스 할 수 있습니다. 연결 스캐너 클라이언트로?
Steve

흐름은 다음과 같습니다. 사진을 찍고 sdcard에 저장 한 다음 스캐너를 업데이트하여 파일 시스템이 업데이트되어 장치 갤러리에서 저장된 사진을 볼 수 있습니다. 스캐너로 그렇게하지 않으면 갤러리에서 다음 장치가 다시 시작된 후 사진이 표시됩니다.
3dmg


6

활동에서 'MediaScannerConnectionClient'를 구현하고이를 활동에 추가합니다.

private void startScan() 
{ 
    if(conn!=null) conn.disconnect();  
    conn = new MediaScannerConnection(YourActivity.this,YourActivity.this); 
    conn.connect(); 
} 

@Override 
public void onMediaScannerConnected() { 
    try{
        conn.scanFile(yourImagePath, "image/*");
       } catch (java.lang.IllegalStateException e){
       }
}

@Override 
public void onScanCompleted(String path, Uri uri) { 
    conn.disconnect(); 
} 

안녕하세요! 우리는 무엇을 알고있는 경우 Uri, 예를 들어, 이미지를 :content://media/external/images/media/1231778
Shajeel 아프

6

이 작품은 나와 함께

File file = ..... // Save file

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));

4
 File folderGIF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/newgif2");    //path where gif will be stored
success = folderGIF.mkdir();    //make directory
 String finalPath = folderGIF + "/test1.gif";  //path of file
.....
/* changes in gallery app if any changes in done*/
 MediaScannerConnection.scanFile(this,
                    new String[]{finalPath}, null,
                    new MediaScannerConnection.OnScanCompletedListener() {
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned " + path + ":");
                            Log.i("ExternalStorage", "-> uri=" + uri);
                        }
                    });

외부 저장소에있는 애니메이션 gif 파일을 저장하고 싶습니다. /storage/emulated/0/Android/data/<PackageName>/files/<FolderName>/xyz.gif 경로가 있습니다. 이제이 파일을 이미지 갤러리에 저장 / 복사하고 거기에 표시하고 싶습니다. 이것을하는 방법.
Zia Ur Rahman

3

여기에서는 비트 맵 형식으로 이미지를로드하고 해당 이미지를 앱 이름 폴더의 sdcard 갤러리에 저장할 수있는 코드를 공유하고 있습니다. 다음 단계를 따라야합니다.

  1. 먼저 이미지 비트 맵 다운로드



     private Bitmap loadBitmap(String url) {
        try {
            InputStream in = new java.net.URL(url).openStream();
            return BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
       }


  1. AndroidManifest.xml 파일에 다음 권한도 제공하십시오.


    uses-permission android:name="android.permission.INTERNET" 
    uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"


  1. 다음은이 작업을 수행하려는 Activty로 작성된 전체 코드입니다.



     void saveMyImage(String appName, String imageUrl, String imageName) {

            Bitmap bmImg = loadBitmap(imageUrl);
            File filename;
            try {
                String path1 = android.os.Environment.getExternalStorageDirectory()
                        .toString();
                File file = new File(path1 + "/" + appName);
                if (!file.exists())
                    file.mkdirs();
                filename = new File(file.getAbsolutePath() + "/" + imageName
                        + ".jpg");
                FileOutputStream out = new FileOutputStream(filename);
                bmImg.compress(Bitmap.CompressFormat.JPEG, 90, out);
                out.flush();
                out.close();
                ContentValues image = new ContentValues();
                image.put(Images.Media.TITLE, appName);
                image.put(Images.Media.DISPLAY_NAME, imageName);
                image.put(Images.Media.DESCRIPTION, "App Image");
                image.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
                image.put(Images.Media.MIME_TYPE, "image/jpg");
                image.put(Images.Media.ORIENTATION, 0);
                File parent = filename.getParentFile();
                image.put(Images.ImageColumns.BUCKET_ID, parent.toString()
                        .toLowerCase().hashCode());
                image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, parent.getName()
                        .toLowerCase());
                image.put(Images.Media.SIZE, filename.length());
                image.put(Images.Media.DATA, filename.getAbsolutePath());
                Uri result = getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
                Toast.makeText(getApplicationContext(),
                        "File is Saved in  " + filename, Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }


  1. 전체 문제를 해결할 수 있기를 바랍니다.

3
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

KITKAT에서 작동하지 않는 것 같습니다. 권한 거부 예외 가 발생하고 앱이 충돌합니다. 그래서 이것을 위해 다음을 수행했습니다.

String path = mediaStorageDir.getPath() + File.separator
                    + "IMG_Some_name.jpg";
CameraActivity.this.sendBroadcast(new Intent(
                             Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
                            .parse("file://" + path)));

도움이되기를 바랍니다.


2

이미지 저장 후 사용

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

3
이것은 작동하지만 최상의 솔루션은 아닙니다. SD 카드가 (재) 장착 될 것이라고 생각하도록 시스템을 속여 전체 SD 카드를 강제로 다시 스캔해야합니다. MediaScanner.scanFile (..)은 이제 추가하려는 파일이있을 때 최상의 솔루션입니다.
pocmo

1
모든 이미지를 검색합니다. 그리고 그것은 단지 하나의 이미지 만 갤러리에 표시 할 때 관련이 없을 수있는 불필요한 데이터 처리를 많이 포함합니다.
Rahul Rastogi

2

MyMediaConnectorClient에 대한 내 코드 :

public class MyMediaConnectorClient implements MediaScannerConnectionClient {

    String _fisier;
    MediaScannerConnection MEDIA_SCANNER_CONNECTION;

    public MyMediaConnectorClient(String nume) {
        _fisier = nume;
    }

    public void setScanner(MediaScannerConnection msc){
        MEDIA_SCANNER_CONNECTION = msc;
    }

    @Override
    public void onMediaScannerConnected() {
        MEDIA_SCANNER_CONNECTION.scanFile(_fisier, null);
    }

    @Override
    public void onScanCompleted(String path, Uri uri) {
        if(path.equals(_fisier))
            MEDIA_SCANNER_CONNECTION.disconnect();
    }
}

0

갤러리 앱에 대한 권한을 부여해야합니다. 홈 화면에서 갤러리 앱 아이콘을 길게 누르고 화면 상단에 나타나는 '앱 정보'를 탭하세요. 그렇게하면 갤러리 앱 설정이 표시됩니다. 이제 권한 탭으로 이동하여 토글하여 스토리지, 카메라 권한을 활성화하십시오. 이제 기본 갤러리 앱으로 이동하면 저장된 이미지를 얻을 수 있습니다.


0

갤러리의 이미지가 대신 표시되지 않으면 중간에 404 유형 비트 맵이 표시 될 수있는 경우에도 문제가 해결됩니다. 갤러리에 이미지를 표시하려면 메타 데이터가 있어야하므로 내 코드에있는 태그를 이미지와 함께 추가하세요.

      String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+ 
      getString(R.string.directory) + System.currentTimeMillis() + ".jpg";

       new File(resultPath).getParentFile().mkdir();

        try {
            OutputStream fileOutputStream = new FileOutputStream(resultPath);
            savedBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e2) {
            e2.printStackTrace();
        }
        savedBitmap.recycle();

        File file = new File(resultPath);
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "Photo");
        values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis ());
        values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
        values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
        values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
        values.put("_data", resultPath);

        ContentResolver cr = getContentResolver();
        cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);




        return  resultPath;

0

이것을 시도하면 생성 된 새 이미지에 대해 방송되므로 이미지가 표시됩니다. 갤러리 내부. photoFile 새로 생성 된 이미지의 실제 파일 경로로 대체

private void galleryAddPicBroadCast() {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri contentUri = Uri.fromFile(photoFile);
        mediaScanIntent.setData(contentUri);
        this.sendBroadcast(mediaScanIntent);
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.