这开始是Android论坛上的一般用户问题。然而,它必然是一个编程问题。这是我的问题。
Android有一项服务 - MediaScanner - 随时可以在后台运行(我相信)SD卡已卸载并重新安装。此服务收集卡上所有媒体文件的数据,并提供可由音乐应用程序查询的SQLite DB。大多数音乐应用程序都使用此服务,因为它可以节省与扫描SD卡相关的电量消耗。
自从我开始使用android以来,我一直遇到一个问题,即即使从SD卡中删除后,与该设备同步的M3U播放列表仍保留在此SQLite DB中。虽然卡上只有大约10个m3u的文件,但我现在已经收集了大约40个播放列表,这些播放列表出现在我使用的任何音乐应用程序中。剩余的播放列表不播放,并且是空的。我可以通过从音乐应用程序中删除它们来手动删除它们,但我厌倦了这样做。必须有更好的方法来删除这些鬼播放列表。
Android Market上有两个应用程序 - SDRescan和Music Scanner,据说可以做到这一点,但它们都不起作用。
我开始编写自己的应用程序来刷新或删除MediaStore数据库并从头开始,但我没有走得太远。我有一个运行以下代码的Android应用程序:
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())));
}
}
答案 0 :(得分:46)
这是一个简单的“基于单一文件的解决方案”:
每当添加文件时,让MediaStore内容提供商使用
了解它sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageAdded)));
对于删除:只需使用getContentResolver()。delete(uri,null,null)(信用转到DDSports)
答案 1 :(得分:17)
好的,我已经完成了。
app不是重新扫描卡片,而是遍历mediastore中的所有播放列表并检查_data字段的长度。我发现对于没有关联M3U文件的所有列表,此字段始终为空。然后它只是找到原始Android音乐应用程序的源代码,找到删除方法并使用它删除任何长度为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日,星期二
我从这篇文章中获得了很多关于我博客的流量,并且有大量来自人们的电子邮件感谢我。很高兴它帮了忙!任何潜在的用户都应该知道我的蹩脚应用程序一旦运行就会崩溃,但实际上应该做它应该做的事情!我一直打算回去修复这种崩溃行为并将其投放市场,希望2013年将成为我这样做的一年。
答案 2 :(得分:11)
您可以使用以下代码请求重新扫描特定文件。
注意:传递的MIME TYPE很重要。我注意到如果我使用&#34; * / *&#34;,那么对于MP3 ID3标签的更改在SQLite中没有正确刷新,但是使用&#34; audio / mp3&#34;工作
MediaScannerConnection.scanFile(
context,
new String[]{ pathToFile1, pathToFile2 },
new String[]{ "audio/mp3", "*/*" },
new MediaScannerConnectionClient()
{
public void onMediaScannerConnected()
{
}
public void onScanCompleted(String path, Uri uri)
{
}
});