如何在Android上刷新MediaStore?

3zwtqj6y  于 2023-02-06  发布在  Android
关注(0)|答案(4)|浏览(126)

这开始是Android论坛上的一个普通用户问题。然而,它已经成为一个编程问题。这是我的问题。
Android有一个服务-MediaScanner-它在后台运行的任何时候(我相信)SD卡被卸载和重新安装。这个服务收集卡上所有媒体文件的数据,并提供一个SQLite数据库,可以查询音乐应用程序。大多数音乐应用程序使用这个服务,因为它节省了电池消耗与扫描SD卡。
自从我开始使用安卓系统,我一直有一个问题,即同步到设备的M3U播放列表仍然在这个SQLite数据库中,即使从SD卡中删除。它已经到了这样的地步,我现在有一个大约40个播放列表的集合显示在我使用的任何音乐应用程序中,尽管只有大约10个M3U文件在卡上。其余的播放列表不播放,和都是空的。我可以通过从音乐应用程序中删除它们来手动删除它们,但我厌倦了这样做。必须有一个更好的方法来删除这些幽灵播放列表。
Android市场上有两个应用程序-SDRescan和音乐扫描器,据说它们正是这样做的,但两个都不起作用。
我开始编写自己的应用程序来刷新或删除MediaStore数据库,从头开始,但我没有走多远。我有一个运行以下代码的安卓应用程序:

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

我已经找到了一些例子,这个代码在线作为一种方式来扫描SD卡,但我没有任何运气,无论如何.任何提示?
完整代码:

package com.roryok.MediaRescan;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;

public class MediaRescan extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 
        setContentView(R.layout.main);
    }

    //Rescan the sdcard after copy the file
    private void rescanSdcard() throws Exception{     
      Intent scanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                Uri.parse("file://" + Environment.getExternalStorageDirectory()));   
      IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
      intentFilter.addDataScheme("file");     
      sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, 
                Uri.parse("file://" + Environment.getExternalStorageDirectory())));    
    }
}
jexiocij

jexiocij1#

下面是一个易于使用的“* 基于单个文件 *”解决方案:

正在添加文件:

每当您添加文件时,请使用以下命令通知MediaStoreContent Provider

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

删除文件:

类似地,当您删除一个文件时,使用以下命令通知MediaStoreContent Provider

getContentResolver().delete(uri, null, null)  // (Credit goes to [DDSports][1])
yuvru6vn

yuvru6vn2#

好吧,我做到了。
这款应用并没有重新扫描卡片,而是遍历了MediaStore中的所有播放列表,并检查了_data字段的长度。我发现,对于所有没有关联M3U文件的列表,这个字段总是空的。然后,这只是一个查找原始Android音乐应用源代码的案例。找到delete方法并使用该方法删除任何长度为0的播放列表。我已将应用程序重命名为PlaylistPurge(因为它不再"重新扫描"),并发布以下代码。
我可能还会在某个地方发布它,无论是在Market上还是在我自己的站点http://roryok.com

package com.roryok.PlaylistPurge;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;

public class PlaylistPurge extends ListActivity {

    private List<String> list = new ArrayList<String>();
    private final String [] STAR= {"*"};

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ListAdapter adapter = createAdapter();
        setListAdapter(adapter);
    }

    /**
     * Creates and returns a list adapter for the current list activity
     * @return
     */
    protected ListAdapter createAdapter()
    {
        // return play-lists
        Uri playlist_uri= MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;    
        Cursor cursor= managedQuery(playlist_uri, STAR, null,null,null);
        cursor.moveToFirst();
        for(int r= 0; r<cursor.getCount(); r++, cursor.moveToNext()){
            int i = cursor.getInt(0);
            int l = cursor.getString(1).length();
            if(l>0){
                // keep any playlists with a valid data field, and let me know
                list.add("Keeping : " + cursor.getString(2) + " : id(" + i + ")");
            }else{
                // delete any play-lists with a data length of '0'
                Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, i);
                getContentResolver().delete(uri, null, null);
                list.add("Deleted : " + cursor.getString(2) + " : id(" + i + ")");
            }
        }       
        cursor.close();
        // publish list of retained / deleted playlists
        ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);

        return adapter;
    }
}

更新:
下面是我博客上一篇关于http://roryok.com/blog/index.php/2010/07/23/clearing-out-deleted-playlists-in-android/应用的文章的链接
更新2:2013年4月9日,星期二
这篇文章给我的博客带来了很大的流量,也收到了大量感谢我的邮件。很高兴它起了作用!任何潜在用户都应该知道,我的蹩脚应用程序现在一运行就崩溃了,但实际上它做了它应该做的事情!我一直打算回去修复这种崩溃行为,并把它推向市场,希望2013年我能做到。

ar7v8xwq

ar7v8xwq3#

可以使用以下代码请求重新扫描特定文件。

  • 注意:传递的MIME类型很重要。我注意到如果我使用“/",对MP3 ID 3标记所做的更改在SQLite中无法正确刷新,但使用“audio/mp3”可以正常工作 *
MediaScannerConnection.scanFile(
    context, 
    new String[]{ pathToFile1, pathToFile2 }, 
    new String[]{ "audio/mp3", "*/*" }, 
    new MediaScannerConnectionClient()
    {
        public void onMediaScannerConnected()
        {
        }
        public void onScanCompleted(String path, Uri uri)
        {
        }
    });
nafvub8i

nafvub8i4#

只需在您活动中添加以下内容:

Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

 MediaScannerConnection.scanFile(
            this, new String[]{"/storage/emulated/0"}, null,
            new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                    Log.i("231","onScanCompleted");
                }
            });

相关问题