Это началось как вопрос об обычном пользователе на форумах Android. Однако этим становятся, при необходимости, вопрос о программировании. Вот моя проблема.
Android имеет службу - MediaScanner - который выполняет в фоновом режиме любое время (я верю), SD-карта размонтирована и повторно смонтирована. Этот сервис собирает данные по всем медиа-файлам на карте и обеспечивает DB SQLite, который может быть запрошен музыкальными приложениями. Большинство музыкальных приложений использует этот сервис, поскольку он экономит на разрядке батареи, связанной со сканированием SD-карты.
Так как я начал использовать андроид, у меня последовательно была проблема, посредством чего плей-листы M3U, синхронизируемые с устройством, остаются в этом DB SQLite, даже будучи удаленным из SD-карты. Это перешло к сути дела, где у меня теперь есть набор приблизительно 40 плей-листов, обнаруживающихся в любом музыкальном приложении, я использую, несмотря на там только быть приблизительно 10 m3u файлами на карте. Остающиеся плей-листы не играют и пусты. Я могу удалить их вручную путем удаления их из музыкального приложения, но я устаю делать это. Должен быть лучший способ удалить эти фантомные плей-листы.
Существует два приложения на Android Market - SDRescan и Музыкальный Сканер, которые, предположительно, делают точно это, но ни один из них не работает.
Я приступил к записи моего собственного приложения, чтобы обновить или удалить базу данных 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())));
}
}
Хорошо, я сделал это.
Вместо повторного сканирования карты приложение перебирает все списки воспроизведения в mediastore и проверяет длину поля _data. Я обнаружил, что для всех списков, не имеющих связанного M3U-файла, это поле всегда пустое. Затем нужно было найти исходный код оригинального приложения android music, найти метод delete и использовать его для удаления всех плейлистов с длиной 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;
}
}
UPDATE:
Вот ссылка на пост в моем блоге о приложении http://roryok.com/blog/index.php/2010/07/23/clearing-out-deleted-playlists-in-android/
UPDATE 2: Вторник, 9 апреля 2013
Я получил много трафика на свой блог благодаря этому посту, и огромное количество писем от людей, благодарящих меня за него. Рад, что это помогло! Все потенциальные пользователи должны знать, что мое дрянное приложение в настоящее время падает, как только вы его запускаете, но на самом деле оно делает то, что должно делать! Я всегда намеревался вернуться и исправить это поведение сбоя и выпустить его на рынок, надеюсь, 2013 год станет годом, когда я это сделаю.