我查看了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(context, MediaProvider.INTERNAL_VOLUME);
} else {
if (uri.getScheme().equals("file")) {
String path = uri.getPath();
String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
Log.d(TAG, "action: " + action + " path: " + path);
if (action.equals(Intent.ACTION_MEDIA_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()"应该返回所有可挂载的卷,我认为您的当前代码应该没问题(它将扫描所有卷)。