我尝试过很多不同的方法来触发MediaScanner,以下是我的结果。
发送广播
最简单和天真的解决方案。它包括从您的代码执行以下指令:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
然而,在KitKat设备中由于缺少必要的权限,这种方法已经不再适用。
MediaScannerWrapper
如此处(根据@Brian的答案)所述,它包装了一个MediaScannerConnection
实例,以便在特定目录上触发scan()
方法。这种方法已被证明对于4.3及以下版本很好用,但在KitKat(4.4+)中仍然没有成功的运行。
FileWalker
有许多Play Store应用程序试图克服MediaStore不更新其数据库的问题之一是ReScan SD。它发送许多不同的广播:
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file://" + Environment.getExternalStorageDirectory())));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/SD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/MicroSD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt/Removable/MicroSD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///storage")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable")));
为了支持KitKat,该程序通过手动触发基目录下每个文件的scan()
方法来尝试支持KitKat。不幸的是,这既需要大量的CPU资源又需要很长时间,因此并不建议使用。
"Shell方式"
在某些情况下,似乎唯一可以在KitKat中正常工作的方法是通过adb shell
发送广播。因此,此代码片段允许您以编程方式执行此操作:
Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory());
这种方法更像是一种hack方式,但目前来说是我能想到的最好的方法。
底线
上述方案实际上适用于所有不是KitKat的内容。这是因为,感谢Justin,已经发现并发布了一个错误到官方追踪器。这意味着,在错误被解决之前,我们没有真正的KitKat支持。
应该使用哪个?在这些中,我会使用MediaScannerWrapper
解决方案,以及shell-ish
方法(最后一个)。