如何在Nexus 7上触发MediaScan?

时间:2013-02-28 23:14:27

标签: android android-intent android-broadcast android-mediascanner

因为我想确保MediaStore拥有最新信息而无需重新启动我想使用我在SO上找到的流行方式触发MediaScanner

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                                 Uri.parse("file://" + Environment.getExternalStorageDirectory())));

这适用于我的三星S2 w / ICS,但不适用于我的Nexus 7 w / JellyBean。 Logcat在我的Nexus 7上显示了这个:

WARN/ActivityManager(480): Permission denied: checkComponentPermission() owningUid=10014
WARN/BroadcastQueue(480): Permission Denial: broadcasting Intent { act=android.intent.action.MEDIA_MOUNTED dat=file:///storage/emulated/0 flg=0x10 } from com.example.foo.bar (pid=17488, uid=10046) is not exported from uid 10014 due to receiver com.android.providers.downloads/.DownloadReceiver
INFO/ActivityManager(480): Start proc com.google.android.music:main for broadcast com.google.android.music/.store.MediaStoreImportService$Receiver: pid=17858 uid=10038 gids={50038, 3003, 1015, 1028}
INFO/MusicStore(17858): Database version: 50
INFO/MediaStoreImporter(17858): Update: incremental Added music: 0 Updated music: 0 Deleted music: 0 Created playlists: 0 Updated playlists: 0 Deleted playlists: 0 Inserted playlist items: 0 Deleted playlist items: 0 Removed orphaned playlist items: 0

理论上,最后一行听起来令人鼓舞,但即使将新文件推送到SD卡(通过adb push),值也始终为0。在我的旧设备(S2)上,它会重新安装SD卡。

我已将以下权限添加到我的AndroidManifest.xml中,但它的行为与没有这些权限的行为相同:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

任何想法/替代品?


修改1:

请注意,我不知道新文件或修改或删除文件的任何文件路径。我只是想确保MediaStore是最新的。

3 个答案:

答案 0 :(得分:12)

以下是基于CommonsWare答案的示例代码:

MediaScannerConnection.scanFile(activity, new String[]{path}, null,
                                new MediaScannerConnection.OnScanCompletedListener() {
    @Override
    public void onScanCompleted(final String path, final Uri uri) {
        Log.i(TAG, String.format("Scanned path %s -> URI = %s", path, uri.toString()));
    }
});

即使在大多数情况下,人们都知道要添加/更新的文件/等等。对于MediaStore,应该遵循CommonsWare的回答,我想发布我的解决方案,我需要以粗略的方式进行,因为我不知道文件路径。我主要用它来测试/演示:

Uri uri = Uri.fromFile(Environment.getExternalStorageDirectory());
activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, uri));

顺便说一句,任何解决方案都不需要权限。

答案 1 :(得分:8)

  

使用我在SO上找到的流行方式

伪造ACTION_MEDIA_MOUNTED广播从来就不是一个合适的解决方案恕我直言。

  

任何想法/替代品?

Use MediaScannerConnection,例如通过its scanFile() static method

答案 2 :(得分:7)

我的答案有点晚了,但它可能会帮助那些保存新文件的人,并希望通过Android Kitkat上的该文件扩展媒体商店:在Android Kitkat上,意图ACTION_MEDIA_MOUNTED被阻止用于非系统应用程序(我认为,因为扫描整个文件系统非常昂贵)。但仍然可以使用意图ACTION_MEDIA_SCANNER_SCAN_FILE将文件添加到媒体商店:

File f = new File(path to the file you would like to add to the media store ...);
try {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    Uri uri = Uri.fromFile(f);
    mediaScanIntent.setData(uri);
    sendBroadcast(mediaScanIntent);
} catch(Exception e) {
    ... 
}