6

因为我想确保 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 是最新的。

4

3 回答 3

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));

顺便说一句,这两种解决方案都不需要权限。

于 2013-03-05T22:50:10.580 回答
8

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

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

有什么想法/替代方案吗?

使用MediaScannerConnection,比如通过它的scanFile()静态方法

于 2013-03-01T02:41:53.873 回答
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) {
    ... 
}
于 2014-08-02T20:25:53.613 回答