MediaControllerCompat 的 getMetadata 返回 null

Posted

技术标签:

【中文标题】MediaControllerCompat 的 getMetadata 返回 null【英文标题】:MediaControllerCompat's getMetadata returns null 【发布时间】:2019-12-17 03:40:30 【问题描述】:

我正在尝试使用 this 视频作为指南在 android 中制作音频应用,但在使用音频元数据创建通知时遇到了问题。

这是我用来从设备中提取音频文件的代码:

public void loadData() 
    ContentResolver contentResolver = context.getContentResolver();

    String selection = Media.IS_MUSIC + "!= 0";
    String[] projection = 
        Media._ID,
        Media.ARTIST,
        Media.TITLE,
        Media.DISPLAY_NAME,
        Media.DURATION,
        Media.ALBUM
    ;

    Cursor cursor = contentResolver.query(
        Media.EXTERNAL_CONTENT_URI, projection, selection, null, null
    );

    if(cursor == null || !cursor.moveToFirst()) return;
    else 
        int size = cursor.getCount();
        metadata = new ArrayList<>(size);
        mediaItems = new ArrayList<>(size);
    

    int
        idIndex          = cursor.getColumnIndex(Media._ID),
        artistIndex      = cursor.getColumnIndex(Media.ARTIST),
        titleIndex       = cursor.getColumnIndex(Media.TITLE),
        displayNameIndex = cursor.getColumnIndex(Media.DISPLAY_NAME),
        durationIndex    = cursor.getColumnIndex(Media.DURATION),
        albumIndex       = cursor.getColumnIndex(Media.ALBUM);

    do 
        String mediaId = cursor.getString(idIndex);
        MediaMetadataCompat data = new MediaMetadataCompat.Builder()
            .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, cursor.getString(idIndex))
            .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, cursor.getString(albumIndex))
            .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, cursor.getString(artistIndex))
            .putString(MediaMetadataCompat.METADATA_KEY_TITLE, cursor.getString(titleIndex))
            .putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, cursor.getString(displayNameIndex))
            .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, cursor.getLong(durationIndex))
            .build();

        metadata.add(data);
        mediaItems.add(new MediaBrowserCompat.MediaItem(
            data.getDescription(),
            MediaItem.FLAG_PLAYABLE
        ));
     while(cursor.moveToNext());

    cursor.close();


public List<MediaItem> getMediaItems() 
    return mediaItems;

这是我的 MediaBrowserService 的 onLoadChildren 代码:

@Override
public void onLoadChildren(@NonNull String parentId,
                           @NonNull Result<List<MediaBrowserCompat.MediaItem>> result
) 
    if(parentId.equals(MEDIA_ROOT_ID)) 
        result.sendResult(source.getMediaItems());
    

最后,抛出错误的代码(我在创建 MediaSession 和 setActive(true) 后调用 createNotifcation()):

private void createNotification() 
    NotificationCompat.Action playAction = new NotificationCompat.Action(
        android.R.drawable.ic_media_play,
        getString(R.string.play),
        MediaButtonReceiver.buildMediaButtonPendingIntent(
            ExoMusicService.this,
            PlaybackStateCompat.ACTION_PLAY
        )
    );
    NotificationCompat.Action pauseAction = new NotificationCompat.Action(
        android.R.drawable.ic_media_pause,
        getString(R.string.pause),
        MediaButtonReceiver.buildMediaButtonPendingIntent(
            ExoMusicService.this,
            PlaybackStateCompat.ACTION_PAUSE
        )
    );
    MediaControllerCompat controller = mediaSession.getController();
    Log.i(LOG_TAG, "createNotification: " + (controller == null)); // false
    MediaMetadataCompat metadata = controller.getMetadata();
    Log.i(LOG_TAG, "createNotification: " + (metadata == null)); // true
    MediaDescriptionCompat description = metadata.getDescription();

    notification = new NotificationCompat.Builder(ExoMusicService.this, PLAYBACK_CHANNEL_ID)
        .setContentTitle(description.getTitle())
        .setContentText(description.getSubtitle())
        .setContentIntent(controller.getSessionActivity())
        .setStyle(
            new MediaStyle()
                .setShowActionsInCompactView(0)
                .setMediaSession(mediaSession.getSessionToken())
                .setShowCancelButton(true)
        )
        .setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(
            ExoMusicService.this,
            PlaybackStateCompat.ACTION_STOP
        ))
        .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
        .addAction(playerManager.isPlaying()? pauseAction : playAction)
        .setSmallIcon(R.drawable.icon)
        .build();

如果我理解正确,我相信这就是与此问题相关的所有代码。 知道我可以忽略什么吗?

【问题讨论】:

【参考方案1】:

在显示通知之前,您应该调用 mediaSession.setMetadata(/* 您的元数据 */)。

元数据应包含有关当前正在播放(或准备、暂停等)的音乐项目的信息。

详情请参考documentation。

【讨论】:

以上是关于MediaControllerCompat 的 getMetadata 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

10G/40G/100G光模块的类型和应用

编码g.711 g.168 g.729 g.723 哪个好

g++、clang++、使用libboost的编译花絮——g++7成功时g++8编译失败;

g是代表啥单位

Flask中g对象,以及g,session,flash之间的区别

g:formatDate 作为 g:textField 上的值