【问题标题】:Android's Media Scanner: How do I remove files?Android 媒体扫描仪:如何删除文件?
【发布时间】:2011-12-05 00:15:38
【问题描述】:

我正在编写一个应用程序,用于删除可能会或可能不会在任何一种媒体库(例如音乐或图片)中列出的文件。虽然我可以使用MediaScannerConnection.scanFile 方法将文件添加 到媒体库,但似乎没有任何调用来通知服务该文件已被删除。将不再存在的文件的路径发送给它也不会产生所需的行为。我应该如何从库中删除 Android 存储中不再存在的项目?

【问题讨论】:

    标签: android android-mediascanner


    【解决方案1】:

    我能够使用这两个问题中的点点滴滴来组合一个方法

    1. What is the String 'volumeName' argument of MediaStore.Audio.Playlists.Members.getContentUri referring to?
    2. How can I refresh MediaStore on Android?

    基本上我只是对每个 MediaStore 类型(音频、视频和图像)运行一个查询,按路径选择并删除我找到的任何记录。

    public static void RemoveAllForPaths(String[] paths, Context context)
    {
        private static final String[] FIELDS = { MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.TITLE };
        if(paths == null || paths.length == 0) return;
        String select = "";
        for(String path : paths)
        {
            if(!select.equals("")) select += " OR ";
            select += MediaStore.MediaColumns.DATA + "=?";
        }
    
        Uri uri;
        Cursor ca;
    
        uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        ca = context.getContentResolver().query(uri, FIELDS, select, paths, null);
        for(ca.moveToFirst(); !ca.isAfterLast(); ca.moveToNext()){
            int id = ca.getInt(ca.getColumnIndex(MediaStore.MediaColumns._ID));
            uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
            context.getContentResolver().delete(uri, null, null);
        }
        ca.close();
    
        // More of the same just setting the URI to Video and Images
    }
    

    我不完全确定这样做有多安全,但这是我迄今为止发现的唯一解决方案,并且一些初步测试似乎正在发挥作用。如果有人对此方法或执行此功能的更好方法有任何进一步的信息,我邀请其他人提交其他答案。

    【讨论】:

    • 对于路径通配符,我添加了select += MediaStore.MediaColumns.DATA + "like ?"; 并将% 附加到我的路径字符串列表中。这将返回特定文件夹中的所有文件
    【解决方案2】:

    Spencer Ruport 的答案是正确的,但 您不需要查询并打开光标 即可删除。 所以对于一个音乐文件,代码很简单:

    public void DeleteMP3FromMediaStore( Context context, String path )
    {
        Uri rootUri = MediaStore.Audio.Media.getContentUriForPath( path );
    
        context.getContentResolver().delete( rootUri, 
            MediaStore.MediaColumns.DATA + "=?", new String[]{ path } );
    }
    

    附:我想评论 Spencer Ruport 的回答,但还没有足够的声誉。

    【讨论】:

    • 更简单、更干净的方式。谢谢。通过提及相关的 where 子句,我也可以将其用于批量删除。
    • 似乎是最合适、最直接、最安全的方式。我希望它适用于所有配置。
    【解决方案3】:

    易如反掌:每当您添加文件时,让MediaStore ContentProvider 知道它使用

    sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(fileToAddInMediaStore)));
    

    对于删除:只需使用

    getContentResolver().delete(Uri.fromFile(fileToDeleteFromMediaStore), null, null)
    

    【讨论】:

    • 你试过你的解决方案了吗?我试过了,这似乎不起作用。
    • 是的,它对我有用。我看到的唯一缺陷是,当我删除文件时,会通知 mediaStore 并在某些设备上重新创建一个空(0 字节)文件。不知道为什么,后来我删了。
    • stackoverflow.com/questions/15147536/… 中所述,这将使应用程序从 Android 4.4 开始崩溃。
    • @BerndS,我正在使用 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE。您提供的链接是关于 Intent.ACTION_MEDIA_MOUNTED。你真的在 4.4 上尝试过我的解决方案吗?
    • @Pascal 刚刚尝试了您的解决方案,它可以工作。不得不等待我的 Nexus 7 获得 KitKat 更新。
    【解决方案4】:

    以下内容对我很有效。您可以使用它删除或添加文件。

    MediaScannerConnection.scanFile(
                    context,
                    new String[]{fileToDelete, fileToAdd},
                    null, null);
    

    【讨论】:

    • 这将在某些设备上创建零字节文件
    • 媒体选择器在删除文件然后重新扫描后仍然显示文件在那里
    【解决方案5】:

    可用的方法是从库中删除该项目。 这篇文章详细表达了如何添加到媒体库或从媒体库中删除。 http://androidyue.github.io/blog/2014/01/19/scan-media-files-in-android/希望对您有所帮助。

    【讨论】:

    • 嗨,我喜欢你在 github 上的帖子,但我似乎无法让“从媒体库中删除”工作。我以编程方式从 sdcard/Tumblr 文件夹中移动文件(因为我喜欢将它们存储在存储卡上而不是内部存储上)。当我这样做时,我需要更新 mediastore 让它知道图像已从内部存储 Tumblr 文件夹中“删除”。但是,无论我用你的代码做什么,我都无法让它工作。 2 问题:(1)如何在内部存储中指定 Tumblr 的路径,(2)我是使用 EXTERNAL_CONTENT_URI 还是 INTERNAL_CONTENT_URI。提前谢谢你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多