Android Scan Media Files - ythy/blog GitHub Wiki

How To Scan A Created File

Now I am going to introduce two ways to add a created file into the media library.

The Simplest Method

Just send a broadcast, as we have posted above. Just send a broadcast intent to MediaScannerReceiver.

String saveAs = "Your_Created_File_Path"
Uri contentUri = Uri.fromFile(new File(saveAs));
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,contentUri);
getContext().sendBroadcast(mediaScanIntent);

The above method maybe has been seen thousands of times. Actually it should work. However I failed and failed in sending broadcast intent. In the following section. I will point out why the sending broadcast not works. Even though you get well on with sending broadcast,it’s strongly recommended to read the Section Why Sending MEDIA_SCANNER_SCAN_FILE broadcast not works.

Use MediaScannerConnection

 public void mediaScan(File file) {
    MediaScannerConnection.scanFile(getActivity(),
            new String[] { file.getAbsolutePath() }, null,
            new OnScanCompletedListener() {
                @Override
                public void onScanCompleted(String path, Uri uri) {
                    Log.v("MediaScanWork", "file " + path
                            + " was scanned seccessfully: " + uri);
                }
            });
}

the scanFile method is introduced since API 8

Why Sending MEDIA_SCANNER_SCAN_FILE broadcast not works

Actually someone may think sending ACTION_MEDIA_SCANNER_SCAN_FILE works on some devices but not on other devices. Actually it’s. Is it a API limit? No, It’s has someting to do with your file path. Take a look at this

 public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Uri uri = intent.getData();
    if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
        // scan internal storage
        scan(context, MediaProvider.INTERNAL_VOLUME);
    } else {
        if (uri.getScheme().equals("file")) {
            // handle intents related to external storage
            String path = uri.getPath();
            String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
            Log.d(TAG, "action: " + action + " path: " + path);
            if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
                // scan whenever any volume is mounted
                scan(context, MediaProvider.EXTERNAL_VOLUME);
            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
                    path != null && path.startsWith(externalStoragePath + "/")) {
                scanFile(context, path);
            }
        }
    }
}

Every part is right except the intent data. I mean the file path. You may hardcode the filepath. This is my example

final String saveAs = "/sdcard/" + System.currentTimeMillis() + "_add.png";
Uri contentUri = Uri.fromFile(new File(saveAs));
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,contentUri);
getContext().sendBroadcast(mediaScanIntent);
Uri uri = mediaScanIntent.getData();
String path = uri.getPath();
String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
Log.i("LOGTAG", "Androidyue onReceive intent= " + mediaScanIntent
                        + ";path=" + path + ";externalStoragePath=" +
                        externalStoragePath);

And this is the output log

LOGTAG Androidyue onReceive intent= Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/1390136305831_add.png };path=/sdcard/1390136305831_add.png;externalStoragePath=/mnt/sdcard

So in the sending broadcast, your action is right, your data schema OK, your data path not null;but your path /sdcard/1390136305831_add.png does not startswith the externalStoragePath /mnt/sdcard/ And so the scan file is actually not called. In conclusion your hardcoding path results in the failure.

原文链接