Ответ 1
Из исходного кода здесь, мы видим, что окончательная реализация сканера имеет два шага для сканирования аудиофайла. Если любой из этих двух шагов завершится неудачно, аудиофайл не будет вставляться в медиа-провайдер.
шаг 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
наконец-то провалится. Медиа файл не будет добавлен в медиа-провайдер наконец.
предлагаемое решение
Поскольку мы знаем, что аудиофайл будет добавлен в
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...