Запустить mediascanner по определенному пути (папке), как? - PullRequest
14 голосов
/ 23 февраля 2012

Я получил этот класс:

import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.util.Log;

public class MediaScannerWrapper implements  
MediaScannerConnection.MediaScannerConnectionClient {
    private MediaScannerConnection mConnection;
    private String mPath;
    private String mMimeType;


    // filePath - where to scan; 
    // mime type of media to scan i.e. "image/jpeg". 
    // use "*/*" for any media
    public MediaScannerWrapper(Context ctx, String filePath, String mime){
        mPath = "/sdcard/DCIM/Camera";
        mMimeType = "jpg";
        mConnection = new MediaScannerConnection(ctx, this);
    }

    // do the scanning
    public void scan() {
        mConnection.connect();
    }

    // start the scan when scanner is ready
    public void onMediaScannerConnected() {
        mConnection.scanFile(mPath, mMimeType);
        Log.w("MediaScannerWrapper", "media file scanned: " + mPath);
    }

    public void onScanCompleted(String path, Uri uri) {
        // when scan is completes, update media file tags
    }
}

Как использовать это в другом классе? Я не знаю, как правильно использовать классы, я пытался, но ничего не работает. Я делаю что-то не так, но я не знаю что, может кто-нибудь помочь мне с этим.

Ответы [ 6 ]

49 голосов
/ 01 августа 2014

История

До Android 4.4 мы могли просто отправить широковещательную рассылку, чтобы запустить медиа-сканер для любого конкретного файла, папки или даже в корне хранилища. Но в 4.4 KitKat это было исправлено разработчиками Android.

Почему я говорю исправлено? Причина проста. Отправка трансляции с использованием MEDIA_MOUNTED в корневом каталоге очень дорога. Запуск Media Scanner - дорогостоящая операция, и ситуация становится еще хуже, когда у пользователя много файлов в хранилище и структурах глубоких папок.

До Android 4.4

Держите это прямо и просто. Если вы ориентируетесь на свое приложение до Android 4.4. Но имейте в виду, что не используйте его в корневом каталоге, если это не является абсолютно необходимым.

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

Из Android 4.4

Есть два пути для вас.

i) Первый очень похож на предыдущий пример, но может работать неэффективно и не рекомендуется.

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

ii) Теперь перейдем к наиболее рекомендуемому и эффективному решению этой проблемы.

Добавьте пути к файлам файлов, которые были обновлены, например, в строковый тип ArrayList

ArrayList<String> toBeScanned = new ArrayList<String>();
toBeScanned.add(item.getFilePath());

Теперь вам нужно запустить статический метод scanFile () класса MediaScannerConnection и передать массив String, содержащий список всех файлов, которые были обновлены и должны быть отсканированы.

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

String[] toBeScannedStr = new String[toBeScanned.size()];
                toBeScannedStr = toBeScanned.toArray(toBeScannedStr);

                MediaScannerConnection.scanFile(getActivity(), toBeScannedStr, null, new OnScanCompletedListener() {

                    @Override
                    public void onScanCompleted(String path, Uri uri) {
                        System.out.println("SCAN COMPLETED: " + path);

                    }
                });
10 голосов
/ 27 февраля 2012

Эй, я узнал, как сделать это с очень простым кодом.

Просто позвоните по этой строке кода:

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

Это должно вызвать mediascanner.

6 голосов
/ 19 марта 2014
   File file = new File(absolutePath);
   Uri uri = Uri.fromFile(file);
   Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
   sendBroadcast(intent);
6 голосов
/ 24 февраля 2012

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

Когда Android загружается, служба mediascanner запускается и запускается черезвсе внешнее хранилище, чтобы найти, есть ли новый медиа-контент, если он найдет его, тогда

  • Добавляет запись этого медиа-контента в базу данных контента
  • Каждая записьбаза данных контента содержит метаданные мультимедийного контента, такие как имя, дата, размер файла, тип файла и т. д.
  • Если база данных контента не обновляется, другие приложения также не смогут получить доступ к этому конкретному медиа-контенту.
  • При запуске медиа-сканера просто обновляется база данных контента

Вместо запуска медиа-сканера вы можете обновить базу данных контента самостоятельно, и это должно решить проблемуm.

Вот объяснение о том, как вставлять, удалять, обновлять с помощью преобразователя содержимого.(Поиск в разделе «Вставка, обновление и удаление данных»)

Редактировать: В этом ответе приведен пример кода.Проверьте ответ от Janusz.

1 голос
/ 27 марта 2016
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}

Ссылка: http://developer.android.com/training/camera/photobasics.html#TaskGallery

Секция Add the Photo to a Gallery

0 голосов
/ 15 июня 2016

Как ответ @Aritra Roy, я решил провести эксперимент по этой проблеме. Что я получил здесь:

  • Intent.ACTION_MEDIA_MOUNTED и Intent.ACTION_MEDIA_SCANNER_SCAN_FILE может принять индивидуальный путь к файлу, поэтому sendBroadcast (новый Intent (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse (filePath))); или sendBroadcast (новое намерение (Intent.ACTION_MEDIA_MOUNTED, Uri.parse (Filepath))); будет действительным.
  • Если вы используете отдельный путь к файлу с Intent.ACTION_MEDIA_MOUNTED на Kitkat или выше, ваше приложение все равно будет аварийно завершать работу
  • Если вы используете Intent.ACTION_MEDIA_SCANNER_SCAN_FILE или MediaScannerConnection на устройстве ниже Kitkat, ваше приложение не будет принудительно закрываться, но метод просто будет работать не так, как вы хотите.

Из этого эксперимента я думаю, что лучший метод для обработки -

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, new MediaScannerConnection.OnScanCompletedListener() {
        public void onScanCompleted(String path, Uri uri) {
            //something that you want to do
        }
    });
} else {
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
            Uri.parse("file://" + imagePath)));
}

Дайте мне знать, если я что-то пропустил

...