¿Cómo puedo actualizar MediaStore en Android?

Esto comenzó como una pregunta general del usuario en los foros de Android. Sin embargo, se ha convertido, por necesidad, en una pregunta de progtwigción. Aquí está mi problema.

Android tiene un servicio – MediaScanner – que se ejecuta en segundo plano en cualquier momento (creo) que la tarjeta SD no está montada y montada nuevamente. Este servicio recostack datos en todos los archivos multimedia de la tarjeta y proporciona una base de datos SQLite que las aplicaciones de música pueden consultar. La mayoría de las aplicaciones de música usan este servicio ya que ahorra en el consumo de batería asociado con el escaneo de la tarjeta SD.

Desde que comencé a usar Android, siempre he tenido un problema por el cual las listas de reproducción de M3U sincronizadas con el dispositivo permanecen en este DB de SQLite incluso después de ser eliminadas de la tarjeta SD. Ha llegado al punto en el que ahora tengo una colección de aproximadamente 40 listas de reproducción en cualquier aplicación de música que utilizo, a pesar de que solo hay alrededor de 10 archivos m3u en la tarjeta. Las listas de reproducción restantes no se reproducen y están vacías. Puedo eliminarlos manualmente eliminándolos de la aplicación de música, pero estoy cansado de hacer esto. Tiene que haber una mejor manera de eliminar estas listas de reproducción fantasmas.

Hay dos aplicaciones en Android Market: SDRescan y Music Scanner, que supuestamente hacen exactamente esto, pero ninguna de ellas funciona.

Me puse a escribir mi propia aplicación para actualizar o eliminar la base de datos de MediaStore y comenzar de cero, pero no estoy llegando muy lejos. Tengo una aplicación para Android que ejecuta el siguiente código:

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

He encontrado algunos ejemplos de este código en línea como una forma de escanear la tarjeta SD, pero no estoy teniendo suerte con eso en absoluto. ¿Algun consejo?

CÓDIGO COMPLETO:

 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()))); } } 

Aquí hay una sencilla ‘solución basada en un único archivo’:

Siempre que agregue un archivo, permita que MediaStore Content Provider lo conozca usando

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

Para eliminación : solo use getContentResolver (). Delete (uri, null, null) (El crédito va a DDSports )

Ok, lo he hecho.

En lugar de volver a explorar la tarjeta, la aplicación recorre todas las listas de reproducción en mediastore y comprueba la longitud del campo _data. Descubrí que para todas las listas sin archivo M3U asociado, este campo siempre estaba vacío. Luego fue solo el caso de encontrar el código fuente para la aplicación de música original de Android, encontrar el método de eliminación y usarlo para eliminar cualquier lista de reproducción con una longitud de 0. He cambiado el nombre de la aplicación PlaylistPurge (ya que no ‘vuelve a escanear ‘más) y estoy publicando el código a continuación.

Probablemente también publique esto en alguna parte, ya sea en Market o en mi propio sitio, 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 list = new ArrayList(); 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; r0){ // 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(this, android.R.layout.simple_list_item_1, list); return adapter; } } 

ACTUALIZAR:

Aquí hay un enlace a una publicación en mi blog sobre la aplicación http://roryok.com/blog/index.php/2010/07/23/clearing-out-deleted-playlists-in-android/

ACTUALIZACIÓN 2: martes, 9 de abril de 2013

Obtuve mucho tráfico en mi blog a partir de esta publicación, y una gran cantidad de correos electrónicos de personas que me lo agradecen. Me alegro de que ayudó! ¡Cualquier usuario potencial debería saber que mi aplicación de mierda actualmente se cuelga tan pronto como la ejecutas, pero en realidad hace lo que se supone que debe hacer! Siempre he tenido la intención de volver atrás y corregir este comportamiento estrepitoso y ponerlo en el mercado, con suerte 2013 será el año en que lo haga.

Puede solicitar un re-escaneo de archivos específicos usando el siguiente código.

NOTA: El TIPO MIME pasado es importante. Noté que los cambios realizados en las tags MP3 ID3 no se actualizaron correctamente en el SQLite si utilicé “* / *”, sin embargo, el uso de “audio / mp3” funcionó

 MediaScannerConnection.scanFile( context, new String[]{ pathToFile1, pathToFile2 }, new String[]{ "audio/mp3", "*/*" }, new MediaScannerConnectionClient() { public void onMediaScannerConnected() { } public void onScanCompleted(String path, Uri uri) { } });