53 votes

Comment puis-je actualiser MediaStore sur Android?

Ce qui a commencé comme un utilisateur à la question sur les forums Android. Cependant, il est devenu, par nécessité, une question de programmation. Voici mon problème.

Android dispose d'un service - MediaScanner - qui s'exécute en arrière-plan à tout moment (je crois) la carte SD est non monté et re-monté. Ce service recueille des données sur tous les fichiers multimédia sur la carte, et fournit un DB SQLite qui peut être interrogée par les applications de musique. La plupart des applications de musique utiliser ce service car il permet d'économiser la batterie-vidange associés à la numérisation de la carte SD.

Depuis que j'ai commencé à utiliser android, j'ai toujours eu un problème selon lequel M3U playlists synchronisée à l'appareil de rester dans ce SQLite DB, même après avoir été supprimés de la Carte SD. Il est arrivé au point où maintenant, j'ai une collection d'environ 40 sélections en montrant dans toute la musique app que j'utilise, bien que seulement environ 10 m3u fichiers sur la carte. Le reste des listes de lecture ne jouent pas, et sont vides. Je peux les supprimer manuellement en les supprimant de l'application musique, mais je suis malade de le faire. Il y a une meilleure façon de supprimer ces fantômes des listes de lecture.

Il y a deux applications sur l'Android Market - SDRescan et de la Musique du Scanner, qui soi-disant faire exactement cela, mais aucun d'eux de travailler.

J'ai décidé d'écrire mon propre application pour actualiser ou supprimer le MediaStore base de données et commencer à partir de zéro, mais je ne suis pas très loin. J'ai une application android qui exécute le code suivant :

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

J'ai trouvé quelques exemples de ce code en ligne comme un moyen de scan de la Carte SD, mais je ne suis pas du tout avoir de la chance avec elle que ce soit. Des conseils à donner?

CODE COMPLET:

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

56voto

Pascal Points 2023

Voici une solution simple basée sur un seul fichier:

Chaque fois que vous ajoutez un fichier, informez le fournisseur de contenu MediaStore en utilisant

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

Pour la suppression : utilisez simplement getContentResolver (). Delete (uri, null, null) (le crédit revient à DDSports )

19voto

roryok Points 1893

Ok, je l'ai fait.

Plutôt que de relancer l'analyse de la carte, l'application parcourt toutes les listes de lecture dans mediastore et vérifie la longueur de la _data champ. J'ai découvert que pour toutes les listes avec aucun fichier M3U, ce champ était toujours vide. Alors c'était juste un cas de trouver le code source de l'original android app de musique, de trouver la méthode delete et en les utilisant pour supprimer toutes les listes de lecture avec une longueur de 0. J'ai renommé l'application PlaylistPurge (puisqu'il n'a pas "rafraîchir" plus) et je suis de poster le code ci-dessous.

Je vais probablement aussi publier ce quelque part, soit sur le Marché ou sur mon propre site, 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;
    }
}

Mise à JOUR:

Voici un lien vers un post sur mon blog à propos de l'application http://roryok.com/blog/index.php/2010/07/23/clearing-out-deleted-playlists-in-android/

Mise à JOUR 2: mardi, avril 9, 2013

J'ai reçu beaucoup de trafic sur mon blog à partir de ce post, et un grand nombre de courriels de gens qui me remercier pour cela. Content que ça a aidé! Tous les utilisateurs potentiels doivent savoir que ma merde application tombe en panne dès que vous l'exécutez, mais en fait, fait ce qu'il est censé faire! J'ai toujours voulu revenir en arrière et corriger ce plantage de comportement et de le mettre sur le marché, espérons que 2013 sera l'année je le fais.

12voto

Michael Points 143

Vous pouvez demander une nouvelle analyse de fichiers spécifiques à l'aide du code suivant.

REMARQUE: le type MIME transmis est important. J'ai remarqué que les modifications apportées aux tags MP3 ID3 ne s'activaient pas correctement dans SQLite si j'utilisais "* / *", mais l'utilisation de "audio / mp3" fonctionnait

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X