Search code examples
androidandroid-mediaplayermediabrowserservicecompat

Get item playing from MediaBrowserService


I have an audio app with the home Activity containing a list of items. The user selects an item and I pass an ID to another Activity which has the controls (play/pause/volume, etc). The audio playback is handed in a MediaBrowserService. I need to detect if the item the user selects is currently playing but I can't figure out how outside of saving the ID in local storage (SharedPrefs or SQlite).

I pass the ID of the item from the second Activity to the MediaBrowserService though a Bundle. I thought I could then retrieve the ID in the second Activity using getExtras() but it always returns 0 or null, depending on which code I use (see below).

I'm not opposed to using local storage but seem like there should be a better way. This is what I have so far:

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();
            ...             
        }
    }
}

Solution

  • media_controller.getMetadata().getDescription().getMediaId() may be what you're looking for. If not, maybe try using MediaMetadataCompat.Builder() to set some metadata to each of your episodes

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

    something like that, I don't think you need to use the METADATA_KEYs either, you can probably replace that with "episode id" or whatever string you want to use as a key.

    edit: if you go the metadata route, you may want to use that to build mediaitems.

    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));
    

    Hope i helped

    edit: using the media items enables you to use the media_controller.getMetadata().getDescription().getMediaId() from above, I think