如何在Android上刷新MediaStore?

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

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

自从我开始使用android之后,我始终有一个问题,M3U播放列表与设备同步,即使在从SD卡中删除之后,仍保留在此SQLite数据库中。 现在我已经收集了大约40个播放列表,在我使用的任何音乐应用程序中出现,尽pipe卡上只有大约10 m3u的文件。 剩下的播放列表不播放,并且是空的。 我可以通过从音乐应用程序中删除它们手动删除它们,但我厌倦了这样做。 必须有一个更好的方法来删除这些幽灵播放列表。

Android电子市场上有两个应用程序 – SDRescan和音乐扫描仪,据说可以做到这一点,但他们都没有工作。

我着手编写自己的应用程序来刷新或删除MediaStore数据库,并从头开始,但我没有太多。 我有一个运行以下代码的Android应用程序:

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

我在网上find了这个代码的一些例子,作为扫描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()))); } } 

这是一个简单的“基于单个文件的解决scheme”:

每当你添加一个文件,让MediaStore Content Provider知道它的使用

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

删除 :只要使用getContentResolver()。delete(uri,null,null)(Credit转到DDSports )

好的,我已经完成了。

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

我可能还会在市场或我自己的网站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日,星期二

从这篇文章中,我收到了很多stream量到我的博客,还有很多人的电子邮件感谢我。 很高兴帮助! 任何潜在的用户应该知道,我的蹩脚的应用程序目前崩溃,只要你运行它,但实际上做它应该做的! 我一直打算回去修复这个崩溃的行为,并将其投放市场,希望2013年能成为我这样做的一年。

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

注意:传递的MIME TYPE很重要。 我注意到对MP3 ID3标签所做的更改没有在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) { } });