SDカードに保存された画像がAndroidのギャラリーアプリに表示されない


92

画像をSDカードに保存しましたが、SDカードを取り外して元に戻すまで、ギャラリーアプリケーションに表示されません。

なぜそうなのか、何か分かりますか?

Galleryアプリケーションには、ファイルの保存時に更新されないキャッシュがあるようです...

実は、私はまた、ギャラリーアプリケーションでジャスト・保存した画像を開いていることとは成功していないにしたい
、これは、この問題についての私の質問ですが。


1
この質問は、このチュートリアルでステップバイステップに答えてきた: stackoverflow.com/questions/30506301/...を
Takermania

回答:


45

システムは、マウントされたSDカードをスキャンして、新しいイメージ(およびその他の)ファイルを検出します。プログラムでファイルを追加する場合は、このクラスを使用できます。

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


4
補足:質問はファイルの追加に関するものですが、MediaScannerConnectionはファイル削除の解決策を提供しません-削除されたファイルの親フォルダーをスキャンするように要求する場合でもそうではありません。
AlikElzin-kilaka 2013

85

より簡単な解決策は、静的簡易メソッドscanFile()を使用することです。

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

ここthisで、アクティビティ(またはコンテキスト)はどこですか、mime-typeは、非標準のファイル拡張子を使用している場合にのみ必要nullで、オプションのコールバック用です(このような単純なケースでは必要ありません)。


2
他の人(そしてグーグル)が提供する放送方法にスポットを当ててください。
Chris.Jenkins 2013年

2
これは、以前のandroidバージョン〜4.0では機能していましたが、4.3以降では機能していないようです。画像がギャラリーアプリに表示されません。
hooby3dfx 2014年

パーフェクト!Android.App.Application.Contextを使用してコンテキストを取得できます
jug

マシュマロで働いた
Hitesh Sahu 2017

66

元の質問およびこの問題が発生する可能性のある他の人への私の回答:

同じ問題がありました。私のアプリでSDカードに保存された画像がすぐにギャラリーに表示されませんでした。いくつか検索したところ、「sdcardに保存」コードの後に​​次の1行のコードが挿入されており、問題が修正されています。

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 14年

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())));
}

「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は、新規/保存されたファイルのFileオブジェクトです。


2
お返事ありがとうございます。実際、私はこのプロジェクトをずっと前に終えました...私が使った解決策が何であったかさえ覚えていません。他のユーザーも、あなたがMyMediaConnectorClient... の実装を提供するなら、あなたのソリューションが役立つと思うかもしれません
Michael Kessler

はい-私は今これで本当の頭痛を抱えています。投稿してください:)
Steve

はい、フローがどのようになっているのかはっきりしていません-MediaScannerConnectionを使用してSDCAARD情報を更新できるので、カメラで写真を撮って新しいファイルをMSCに渡し、ファイルにアクセスできます。接続スキャナークライアントで?
Steve

フローは次のとおりです。写真を撮り、それをSDカードに保存してから、スキャナーを更新します。これにより、ファイルシステムが更新され、保存された写真がデバイスギャラリーに表示されます。スキャナーでこれを行わない場合、ギャラリーで次のデバイスの再起動後に写真が表示されます。
3dmg 2010

7

エミュレータに「Dev Tools」というアプリがあります

それをクリックして「メディアスキャン」を選択します。すべての画像がスキャンされます


知ってよかった、あなたがそれを言う前に私が知っていた唯一の方法は電話を再起動することだ:)
ミシュキン

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 Afzal

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、2012年

1
これにより、すべての画像が検索されます。また、ギャラリーに表示する画像が1つしかない場合は無関係である可能性がある多くの不要なデータ処理が含まれます。
Rahul Rastogi、2014

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

Galleryアプリに権限を与える必要があります。ホーム画面のギャラリーアプリアイコンを長押しして、画面上部にポップアップ表示される[アプリ情報]をタップします。これを行うと、ギャラリーアプリの設定が表示されます。次に、[権限]タブに移動して、ストレージとカメラの権限を切り替えて有効にします。次に、ネイティブギャラリーアプリに移動すると、保存した画像を取得できます。


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.