代码之家  ›  专栏  ›  技术社区  ›  roryok

如何在Android上刷新MediaStore?

  •  48
  • roryok  · 技术社区  · 15 年前

    这一开始只是Android论坛上的一个普通用户问题。然而,它必然成为一个编程问题。这是我的问题。

    Android有一个服务——MediaScanner——它可以在任何时候(我相信)卸下SD卡并重新安装时在后台运行。此服务收集卡上所有媒体文件的数据,并提供可由音乐应用程序查询的SQLite数据库。大多数音乐应用程序使用此服务,因为它节省了与扫描SD卡相关的电池消耗。

    自从我开始使用android以来,我一直遇到一个问题,即即使从SD卡上删除了M3U播放列表,同步到设备的M3U播放列表仍然保留在这个SQLite DB中。它已经到了这样一个地步,我现在有大约40个播放列表的集合出现在我使用的任何音乐应用程序中,尽管卡上只有大约10个m3u文件。其余播放列表不播放,并且为空。我可以通过从音乐应用程序中删除它们来手动删除它们,但我厌倦了这样做。必须有更好的方法来删除这些鬼播放列表。

    安卓市场上有两款应用软件——SDRescan和Music Scanner,据说它们确实可以做到这一点,但都不起作用。

    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())));    
        }
    }
    
    3 回复  |  直到 15 年前
        1
  •  56
  •   Pascal    6 年前

    '解决方案:

    添加 文件,通知 MediaStore Content Provider 使用:

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

    删除文件:

    删除 文件,通知 使用:

    getContentResolver().delete(uri, null, null)  // (Credit goes to [DDSports][1])
    
        2
  •  19
  •   roryok    13 年前

    好的,我做了。

    该应用程序不需要重新扫描卡片,而是遍历mediastore中的所有播放列表,并检查\u数据字段的长度。我发现对于所有没有关联M3U文件的列表,这个字段总是空的。然后它只是一个为原始的android音乐应用程序找到源代码的例子,找到delete方法并使用它删除任何长度为0的播放列表。我已经重命名了应用程序playlippurge(因为它不再'重新扫描'),并张贴下面的代码。

    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/

    这篇文章让我的博客获得了大量的流量,还有很多人发来的感谢我的邮件。很高兴有帮助!任何潜在用户都应该知道,我的烂应用程序目前崩溃,只要你运行它,但实际上做了它应该做的!我一直打算回去,纠正这种崩溃的行为,并把它推向市场,希望2013年将是我这样做的一年。

        3
  •  12
  •   Michael    13 年前

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

    注意:传递的MIME类型很重要。我注意到,如果我使用“*/*”,对mp3id3标记所做的更改在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)
            {
            }
        });
    
    推荐文章