扫描Android SD卡以获取新文件

Bri*_*ian 11 media android sd-card android-mediascanner

我的应用程序允许用户将图像保存到SD卡.但是我不知道如何卸下并重新安装SD卡之前如何让它出现在画廊中.我已经用Google搜索了几天这个问题,但我不确定如何让它自动出现.我找到了 这个链接,但我不确定如何使用该类.这是我用来保存文件.在try catch块的底部是我想要扫描sd卡以获取新媒体的地方.

    FileOutputStream outStream = null;
    File file = new File(dirPath, fileName);
    try {
        outStream = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();
    } catch {
         ...
    }
Run Code Online (Sandbox Code Playgroud)

如果有人能指出我正确的方向,我将不胜感激.

Seb*_*ano 9

我尝试了很多不同的方法来触发MediaScanner,这些都是我的结果.

SendBroadcast

最简单,最天真的解决方案.它包括从您的代码执行以下指令:

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
              Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Run Code Online (Sandbox Code Playgroud)

但是,由于缺少必要的权限,这在KitKat设备中不再有效.


MediaScannerWrapper

正如这里发布的那样(根据@ 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")));
Run Code Online (Sandbox Code Playgroud)

并尝试通过scan()在基本目录的每个文件上手动触发方法来支持KitKat .不幸的是,这是非常耗费CPU和耗时的,因此不太推荐.


"贝壳方式"

在某些情况下,唯一似乎与KitKat一起工作的是通过发送广播adb shell.所以,这段代码可以让你做到这一点编程方式:

Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory());
Run Code Online (Sandbox Code Playgroud)

它更多的是做一个黑客十岁上下的方式,但此刻却是我能拿出最好的.


底线

上述每个解决方案的实际工作的,是不是奇巧一切.这是因为,由于贾斯汀,一个错误已被发现并发布到官方跟踪.这意味着,直到错误是冰释前嫌,我们剩下的没有真正的奇巧的支持.

哪一个使用?在这些,我会使用MediaScannerWrapper的解决方案,与一起shell-ish的方法(最后一个).

  • 当我使用adb shell从命令行发送广播时,它适用于新文件和已删除的文件.但它无法以编程方式在KitKat上以新文件或删除文件的方式工作.我正在测试音频音乐文件并使用模拟器API 19. (2认同)

Bri*_*ian 5

由于我发布的最后一个答案显然不是一个合适的方法,我在这里找到了另一种方法.您基本上创建一个包装类,初始化它,然后调用scan()方法.非常有用的帖子.如果这也不合适,请告诉我.