我看了一下Android开源代码(Android 4.1)
有一个名为 /packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java 的文件
它有以下代码:
@Override
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);
}
}
}
}
如您所见,它将检查 ACTION_MEDIA_MOUNT(您使用的)并调用 scan()。但是,它将使用硬编码的 MediaProvier.EXTERNAL_VOLUME(而不是传递的文件 URI)。
回答您的问题,您更改代码没有意义。任何带有文件模式的 URI 都可以正常工作。
但是,供应商有可能会修改此代码。
还有一件事情。Android 4.2 引入了多用户概念,每个用户都有自己的外部存储。基于此,显示的代码可能已更改。
更新 1
这真有趣。最初,我只是浏览了 MediaScannerReceiver 的一部分,并认为它只会扫描一个外部卷。但是,在您告诉我您查看了代码并询问它是否可以工作之后。我进一步调查,发现它会搜索所有可挂载的卷(如你所说)。
据我了解,它通过以下执行路径(它以伪Java代码的形式忽略所有实例化等等)
- MediaScannerReceiver.onReceive 调用 scan(context, MediaProvider.EXTERNAL_VOLUME);
- MediaScannerReceiver.scan 调用 context.startService(new Intent(context, MediaScannerService.class).putExtras(args)); 其中 args 包含键/值对 "volume"=MediaProvider.EXTERNAL_VOLUME)
- MediaScannerService.onStartCommand 调用 mServicehandler.sendMessage
- MediaScannerService.ServiceHandler.handleMessage 接收消息并调用等效于 scan(StorageManager.getVolumePaths(),MediaProvider.EXTERNAL_VOLUME)
- MediaScannerService.scan 调用 MediaScanner.scanDirectories
- MediaScanner 一个一个地遍历每个目录
考虑到“StorageManager.getVolumePaths()”应该返回所有可挂载的卷,我认为你应该对你当前的代码没问题(它将扫描所有卷)。