我尝试了很多不同的方法来触发 MediaScanner,这些是我的结果。
发送广播
最简单天真的解决方案。它包括从您的代码中执行以下指令:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
但是,由于缺少所需的权限,这不再适用在 KitKat 设备中。
MediaScannerWrapper
正如here 发布的那样(根据@Brian 的回答),它包括包装MediaScannerConnection 实例,以便在特定目录上触发scan() 方法。这种方法已被证明在 4.3 及以下版本中运行良好,但在 KitKat (4.4+) 中仍然没有运气。
FileWalker
试图克服 MediaStore 缺乏更新其数据库的承诺的众多 Play 商店应用之一是 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")));
并尝试通过在基目录的每个文件上手动触发 scan() 方法来支持 KitKat。不幸的是,这既非常消耗 CPU 又非常耗时,因此不太推荐。
“外壳方式”
在某些情况下,唯一似乎可以与 KitKat 一起使用的是通过 adb shell 发送广播。因此,这个 sn-p 允许您以编程方式执行此操作:
Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory());
这更像是一种hack-ish方式,但目前是我能想到的最好的方式。
底线
上述每个解决方案实际上都适用于不是 KitKat 的所有东西。这是因为,感谢Justin,发现了一个错误并将其发布给official Tracker。这意味着,在解决该错误之前,我们将无法获得真正的 KitKat 支持。
使用哪一个?其中,我会使用MediaScannerWrapper 解决方案,以及shell-ish 方法(最后一种)。