15

私はこのクラスを取得しました:

import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.util.Log;

public class MediaScannerWrapper implements  
MediaScannerConnection.MediaScannerConnectionClient {
    private MediaScannerConnection mConnection;
    private String mPath;
    private String mMimeType;


    // filePath - where to scan; 
    // mime type of media to scan i.e. "image/jpeg". 
    // use "*/*" for any media
    public MediaScannerWrapper(Context ctx, String filePath, String mime){
        mPath = "/sdcard/DCIM/Camera";
        mMimeType = "jpg";
        mConnection = new MediaScannerConnection(ctx, this);
    }

    // do the scanning
    public void scan() {
        mConnection.connect();
    }

    // start the scan when scanner is ready
    public void onMediaScannerConnected() {
        mConnection.scanFile(mPath, mMimeType);
        Log.w("MediaScannerWrapper", "media file scanned: " + mPath);
    }

    public void onScanCompleted(String path, Uri uri) {
        // when scan is completes, update media file tags
    }
}

他のクラスでどのように使用しますか?クラスを正しく使用する方法がわかりません。試しましたが、何も機能していません。私は何か間違ったことをしますが、何がわからないので、誰かがこれを手伝ってくれますか。

4

6 に答える 6

52

物語

Android 4.4 より前は、ブロードキャストを送信するだけで、特定のファイルやフォルダー、さらにはストレージのルートでメディア スキャナーをトリガーすることができました。しかし、4.4 KitKat から、これは Android 開発者によって修正されました。

なぜ固定と言うのですか?理由は簡単です。ルート ディレクトリで MEDIA_MOUNTED を使用してブロードキャストを送信すると、非常にコストがかかります。メディア スキャナーの実行はコストのかかる操作であり、ユーザーがストレージや深いフォルダー構造に多くのファイルを持っている場合、状況はさらに悪化します。

Android 4.4 より前

まっすぐでシンプルにしてください。Android 4.4 より前のアプリをターゲットにしている場合。ただし、どうしても必要な場合を除き、ルート ディレクトリでは使用しないでください。

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

Android4.4以降

あなたには2つの方法があります。

i) 最初のものは前の例と非常によく似ていますが、効率的に動作しない可能性があり、推奨されません。

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

ii) では、この問題に対する最も推奨される効率的な解決策に移りましょう。

このように、更新されたファイルのファイルパスを String 型の ArrayList に追加します

ArrayList<String> toBeScanned = new ArrayList<String>();
toBeScanned.add(item.getFilePath());

ここで、MediaScannerConnection クラスの scanFile() 静的メソッドを実行し、更新済みでメディア スキャンが必要なすべてのファイルのリストを含む String 配列を渡す必要があります。

個々のファイルのスキャンが終了したときに応答するリスナーを配置することもできます。

String[] toBeScannedStr = new String[toBeScanned.size()];
                toBeScannedStr = toBeScanned.toArray(toBeScannedStr);

                MediaScannerConnection.scanFile(getActivity(), toBeScannedStr, null, new OnScanCompletedListener() {

                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        System.out.println("SCAN COMPLETED: " + path);

                    }
                });
于 2014-08-01T18:33:43.537 に答える
10

ちょっと、非常に単純なコードでそれを行う方法を見つけました。

次のコード行を呼び出すだけです。

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

これにより、mediascanner がトリガーされます。

于 2012-02-27T09:00:22.533 に答える
7

Android には、メディア スキャナがデバイス上に存在するすべてのメディア コンテンツを追跡するために使用するコンテンツ データベースがあります。

Android が起動すると、mediascanner サービスが起動し、外部ストレージ全体を実行して、新しいメディア コンテンツがあるかどうかを調べます。

  • そのメディア コンテンツのエントリをコンテンツ データベースに追加します。
  • コンテンツ データベースの各エントリには、名前、日付、ファイル サイズ、ファイルの種類などのメディア コンテンツのメタデータが含まれています。
  • そのため、メディア コンテンツを変更する場合は、コンテンツ データベースも更新する必要があります。
  • コンテンツ データベースが更新されていない場合、他のアプリケーションもその特定のメディア コンテンツにアクセスできなくなります。
  • メディア スキャナを実行すると、コンテンツ データベースが更新されるだけです

メディア スキャナを実行する代わりに、コンテンツ データベースを自分で更新すると、問題が解決するはずです。

コンテンツ リゾルバーを使用した挿入、削除、更新の方法について説明します。(「データの挿入、更新、および削除」セクションを検索してください)

編集: この回答にはサンプル コードがあります。Janusz による回答を確認してください。

于 2012-02-24T11:35:07.197 に答える
6
   File file = new File(absolutePath);
   Uri uri = Uri.fromFile(file);
   Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
   sendBroadcast(intent);
于 2014-03-19T06:34:08.857 に答える
1
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}

参考:http ://developer.android.com/training/camera/photobasics.html#TaskGallery

Add the Photo to a Galleryセクション_

于 2016-03-27T14:13:58.847 に答える
0

@Aritra Roy の回答として、この問題について実験を行うことにしました。ここで得たものは次のとおりです。

  • Intent.ACTION_MEDIA_MOUNTED と Intent.ACTION_MEDIA_SCANNER_SCAN_FILE は個別のファイル パスを受け入れることができるため、 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(filePath))); または sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse(filePath))); 有効になります。
  • Kitkat 以降で Intent.ACTION_MEDIA_MOUNTED を使用して個別のファイル パスを使用すると、アプリケーションが引き続きクラッシュします。
  • Kitkat より下位のデバイスで Intent.ACTION_MEDIA_SCANNER_SCAN_FILE または MediaScannerConnection を使用する場合、アプリケーションは強制終了しませんが、メソッドは単に希望どおりに機能しません。

その実験から、処理する最良の方法は

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, new MediaScannerConnection.OnScanCompletedListener() {
        public void onScanCompleted(String path, Uri uri) {
            //something that you want to do
        }
    });
} else {
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + imagePath)));
}

何か見逃した場合はお知らせください

于 2016-06-15T06:33:47.390 に答える