【问题标题】:Manual add song to Mediastore as a music track手动将歌曲作为音乐曲目添加到 Mediastore
【发布时间】:2016-04-22 18:46:27
【问题描述】:

我想创建一个音乐播放器,它可以在线下载歌曲并将其添加到 MediaStore。我正在使用下载管理器并允许 MediaScanner 在下载完成后扫描此文件。

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

在 android 5.0 及更高版本中运行良好。
但是这首歌是使用编解码器(opus)下载的,在棒棒糖版本以下的 android 中不支持,因此 MediaScanner 不会将此文件添加到 MediaStore。

这是我的问题,我的应用可以播放 opus 编解码器,但下载后 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);
        }
    }
}

【问题讨论】:

    标签: java android android-mediascanner


    【解决方案1】:

    从源代码here我们可以看到扫描器的最终实现有两个步骤来扫描音频文件。如果这两个步骤中的任何一个失败,音频文件将不会插入到媒体提供程序中。

    第一步检查文件扩展名

    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编解码器的通用容器是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;
    }
    

    对于 5.0 之前的 Android 版本,扫描仪可能会在此步骤失败。由于缺乏内置的 opus 编解码器支持,setDataSource 最后会失败。媒体文件最终不会被添加到媒体提供者中。

    建议的解决方案

    因为我们知道音频文件会被添加到

    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
    

    我们可以手动进行数据库操作。如果您希望您的音频文件与数据库中的其他音频文件保持一致,您必须自己检索所有元数据。既然你可以播放作品文件,我认为检索元数据很容易。

    // 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...
    

    【讨论】:

    • 谢谢。这帮助我找出了为什么我转码为作品的所有音频文件都没有出现在音乐应用程序中...
    【解决方案2】:

    您可以使用MediaScannerConnection 要求Android 扫描要作为媒体包含的文件。您需要使用 scanFile() 静态方法。

    【讨论】:

      猜你喜欢
      • 2014-04-19
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      相关资源
      最近更新 更多