Как я могу обновить MediaStore на Android? - PullRequest
48 голосов
/ 21 июля 2010

Это началось как общий вопрос пользователя на форумах Android.Однако это стало, по необходимости, вопросом программирования.Вот моя проблема.

В Android есть служба MediaScanner, которая работает в фоновом режиме в любое время (как мне кажется), когда SD-карта не установлена ​​и не смонтирована.Эта служба собирает данные обо всех медиафайлах на карте и предоставляет базу данных SQLite, к которой могут обращаться музыкальные приложения.Большинство музыкальных приложений используют этот сервис, поскольку он экономит заряд батареи, связанный со сканированием SD-карты.

С тех пор как я начал использовать Android, у меня постоянно возникала проблема, из-за которой списки воспроизведения M3U, синхронизированные с устройством, остаются в этой базе данных SQLite даже после удаления с SD-карты.Я дошел до того, что теперь у меня есть коллекция из около 40 плейлистов, которые отображаются в любом музыкальном приложении, которое я использую, несмотря на то, что на карте было всего около 10 m3u файлов.Остальные плейлисты не воспроизводятся и пусты.Я могу удалить их вручную, удалив их из музыкального приложения, но мне это надоело.Должен быть лучший способ удалить эти призрачные плейлисты.

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

Ответы [ 3 ]

46 голосов
/ 13 февраля 2013

Вот простое «решение на основе одного файла»:

Всякий раз, когда вы добавляете файл, сообщите поставщику контента MediaStore об этом, используя

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

Для удаление : просто используйте getContentResolver (). Delete (uri, null, null) (Кредит идет на DDSports )

17 голосов
/ 22 июля 2010

Хорошо, я сделал это.

Вместо того, чтобы повторно сканировать карту, приложение просматривает все списки воспроизведения в 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: вторник, 9 апреля 2013 г.

Я получил много трафика на мой блог из этого поста и огромное количествописем от людей, благодаривших меня за это.Рад, что выручил!Любые потенциальные пользователи должны знать, что мое дрянное приложение в настоящий момент падает, как только вы его запускаете, но на самом деле делает то, что должно!Я всегда собирался вернуться и исправить это сбойное поведение и выпустить его на рынок, надеюсь, 2013 год будет годом, когда я это сделаю.

11 голосов
/ 20 декабря 2012

Вы можете запросить повторное сканирование определенных файлов, используя следующий код.

ПРИМЕЧАНИЕ. Переданный 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)
        {
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...