Запустить mediascanner по определенному пути (папке), как?
Я получил этот класс:
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 ответов
Эй, я узнал, как сделать это с очень простым кодом.
Просто назовите эту строку кода:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
Это должно вызвать Medascanner.
История
До 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);
}
});
В Android есть база данных контента, которая используется медиа-сканером для отслеживания всего медиа-контента, присутствующего на устройстве.
Когда Android загружается, служба mediascanner запускается и проходит через все внешнее хранилище, чтобы определить, есть ли новый медиа-контент, если он найдет его,
- Он добавляет запись этого медиа-контента в базу данных контента
- Каждая запись в базе данных контента содержит метаданные медиаконтента, такие как имя, дата, размер файла, тип файла и т. Д.
- Поэтому, когда вы вносите изменения в мультимедийный контент, вам также необходимо обновить базу данных контента.
- Если база данных контента не обновляется, другие приложения также не смогут получить доступ к этому конкретному медиаконтенту.
- Запуск медиа-сканера просто обновляет базу данных контента
Вместо запуска медиа-сканера вы можете обновить базу данных контента самостоятельно, и это должно решить проблему.
Вот объяснение того, как вставлять, удалять, обновлять, используя распознаватель контента. (Поиск по разделу "Вставка, обновление и удаление данных")
Изменить: в этом ответе есть образец кода. Проверьте ответ от Janusz.
File file = new File(absolutePath);
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
sendBroadcast(intent);
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
Add the Photo to a Gallery
Раздел
Как ответ @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)));
}
Дайте мне знать, если я что-то пропустил