从 MediaBrowserService 获取正在播放的项目

Posted

技术标签:

【中文标题】从 MediaBrowserService 获取正在播放的项目【英文标题】:Get item playing from MediaBrowserService 【发布时间】:2020-01-05 21:33:31 【问题描述】:

我有一个音频应用程序,其主页 Activity 包含项目列表。用户选择一个项目,我将一个 ID 传递给另一个具有控件(播放/暂停/音量等)的 Activity。音频播放上交MediaBrowserService。我需要检测用户选择的项目当前是否正在播放,但我无法弄清楚如何将 ID 保存在本地存储(SharedPrefs 或 SQlite)中。

我通过Bundle 将第二个Activity 中的项目ID 传递给MediaBrowserService。我以为我可以使用 getExtras() 在第二个 Activity 中检索 ID,但它总是返回 0 或 null,具体取决于我使用的代码(见下文)。

我不反对使用本地存储,但似乎应该有更好的方法。这是我目前所拥有的:

public class EpisodeActivity extends Activity 
    private MediaBrowserCompat mMediaBrowserCompat;

    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        final Bundle extras = new Bundle();
        extras.putInt("episodeid", getIntent().getExtras().getInt("episodeid")); //passed in from Home Activity

        mMediaBrowserCompat = new MediaBrowserCompat(
                this,
                new ComponentName(this, MediaPlayerService.class),
                mMediaBrowserCompatConnectionCallback,
                extras
        );

        mPlayButton.setOnClickListener(view -> 

            final Bundle extras = new Bundle();
            extras.putInt("episodeid", getIntent().getExtras().getInt("episodeid")); //passed in from Home Activity

            String url = "http://www.example.com/media.mp3"

            MediaControllerCompat.getMediaController(mActivity).getTransportControls().playFromUri(Uri.parse(uri), extras);
        );


        if (MediaControllerCompat.getMediaController(mActivity).getPlaybackState() != null &&
            MediaControllerCompat.getMediaController(mActivity).getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING) 

            int episodeID = mMediaBrowserCompat.getExtras().getInt("episodeid"); //always returns 0

            //also tried this but getExtras is null
            int episodeID = MediaControllerCompat.getMediaController(mActivity).getExtras().getInt("episodeid");

        
    


public class MediaPlayerService extends MediaBrowserServiceCompat 

    private MediaSessionCompat mMediaSessionCompat;

    @Override
    public void onCreate() 
        super.onCreate();

        final ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class);
        mMediaSessionCompat = new MediaSessionCompat(getApplicationContext(), getString(R.string.app_name), mediaButtonReceiver, null);
        mMediaSessionCompat.setCallback(mMediaSessionCallback);
        ...
           

    private MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() 
        @Override
        public void onPlayFromUri(final Uri uri, final Bundle extras) 
            super.onPlayFromUri(uri, extras);

            int episodeId = extras.getInt("episodeid");

            String url = GetUrl(episodeId);

            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(uri);
            mMediaPlayer.prepareAsync();
            ...             
        
    

【问题讨论】:

【参考方案1】:

media_controller.getMetadata().getDescription().getMediaId() 可能是您正在寻找的。如果没有,也许可以尝试使用 MediaMetadataCompat.Builder() 为每个剧集设置一些元数据

MediaMetadataCompat.Builder().putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, episodeID).build()

类似的东西,我认为您也不需要使用 METADATA_KEY,您可以将其替换为“episode id”或您想用作键的任何字符串。

编辑:如果您使用元数据路线,您可能希望使用它来构建媒体项。

MediaMetadataCompat episode_meta = new MediaMetadataCompat.Builder()
                    .putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, episodeID)
                    .build();

episode_mediaitem = new MediaBrowserCompat.MediaItem(episode_meta.getDescription(), MediaBrowserCompat.MediaItem.FLAG_PLAYABLE));

希望对我有所帮助

编辑:我认为使用媒体项目可以让您使用上面的 media_controller.getMetadata().getDescription().getMediaId()

【讨论】:

【参考方案2】:
mPlayButton.setOnClickListener(view -> 

        final Bundle extras = new Bundle();
        extras.putInt("episodeid", getIntent().getExtras().getInt("episodeid")); //passed in from Home Activity

        String url = "http://www.example.com/media.mp3"

        MediaControllerCompat.getMediaController(mActivity).getTransportControls().playFromUri(Uri.parse(uri), extras);
    );

这里你应该在解析 Uri 时用 url 代替 uri。

【讨论】:

以上是关于从 MediaBrowserService 获取正在播放的项目的主要内容,如果未能解决你的问题,请参考以下文章

带有 ExoPlayer 和 PlayerControlView 的 MediaBrowserService - 如何从 UI (PlayerControlView) 访问播放器实例?

将媒体项添加到 MediaBrowserService

是否可以连接到 Spotify 的 MediaBrowserService?

前台 MediaBrowserService 在应用退出时被终止

如何在 ReactJS 中获取没有正斜杠的路由名称

ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效