Руководство добавляет песню в Mediastore как музыкальный трек

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

DownloadManager.Request request .... request.allowScanningByMediaScanner(); ... downloadManager.enqueue(request); 

Это хорошо работает в Android 5.0 и выше.
Но песня была загружена с использованием кодека ( opus ), который не поддерживается в android ниже версии lollipop, поэтому MediaScanner не добавляет этот файл в MediaStore.

Это моя проблема, мое приложение может играть opus codec, но песня не существовала в MediaStore после ее загрузки, поэтому мое приложение не может найти эту песню.

Как заставить MediaScanner добавить загруженный файл в MediaStore.Audio в качестве музыкальной дорожки. Если не удается, как я могу вручную добавить эту песню в MediaStore.Audio после завершения загрузки:

 public class BroadcastDownloadComplete extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.DOWNLOAD_COMPLETE")) { //addSongToMediaStore(intent); } } } 

Solutions Collecting From Web of "Руководство добавляет песню в Mediastore как музыкальный трек"

Из исходного кода здесь мы видим, что окончательная реализация сканера имеет два шага для сканирования аудиофайла. Если любой из этих двух шагов завершится неудачно, аудиофайл не будет вставляться в медиа-провайдер.

Шаг 1 проверьте расширение файла

 static bool FileHasAcceptableExtension(const char *extension) { static const char *kValidExtensions[] = { ".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac", ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota", ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf", ".avi", ".mpeg", ".mpg" }; static const size_t kNumValidExtensions = sizeof(kValidExtensions) / sizeof(kValidExtensions[0]); for (size_t i = 0; i < kNumValidExtensions; ++i) { if (!strcasecmp(extension, kValidExtensions[i])) { return true; } } return false; } 

Дополнительные расширения были добавлены с Android 5.0. Общий контейнер для opus codec – ogg , это расширение существует до Android 5.0. Предположим, что расширение вашего аудиофайла ogg , процесс сканирования на этом этапе прекрасен.

Step2 получить метаданные

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

 sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); int fd = open(path, O_RDONLY | O_LARGEFILE); status_t status; if (fd < 0) { // couldn't open it locally, maybe the media server can? status = mRetriever->setDataSource(path); } else { status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL); close(fd); } if (status) { return MEDIA_SCAN_RESULT_ERROR; } 

Для версии Android до 5.0 сканер может не работать на этом этапе. Из-за отсутствия встроенной поддержки opus-кодека, setDataSource то setDataSource . В конце концов медиа-файл не будет добавлен в медиа-провайдер.

Предлагаемое решение

Поскольку мы знаем, что аудиофайл будет добавлен в

 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 

Мы можем работать с базой данных вручную. Если вы хотите, чтобы ваш аудиофайл соответствовал другим аудиофайлам в базе данных, вам необходимо получить все метаданные самостоятельно. Поскольку вы можете воспроизвести файл opus, я думаю, что легко получить метаданные.

 // retrieve more metadata, duration etc. ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Audio.AudioColumns.DATA, "/mnt/sdcard/Music/example.opus"); contentValues.put(MediaStore.Audio.AudioColumns.TITLE, "Example track"); contentValues.put(MediaStore.Audio.AudioColumns.DISPLAY_NAME, "example"); // more columns should be filled from here Uri uri = getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues); Log.d(TAG, uri.toString()); 

После этого приложение может найти аудиофайл.

 getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI... 

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