Search code examples
androidexoplayer2.xandroid-mediasession

Inactive media session not restarted


I've followed the documentation regarding restarting an inactive media session but it's not working for me. According to the documentation as long as you have the proper entry in the AndroidManifest it should just work.

In the logcat, I can see it's connecting to the MediaBrowserService but nothing happens:

2023-02-14 13:23:20.187 11970-11970 MediaBrowserCompat                       D  Connecting to a MediaBrowserService.
2023-02-14 13:23:20.216 11970-11970 ExoPlayerImpl                            I  Init 690e213 [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33]
2023-02-14 13:23:20.253 11970-11970 ExoPlayerImpl                            I  Release 690e213 [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33] [media3.common, media3.exoplayer, media3.decoder, media3.datasource, media3.extractor]
2023-02-14 13:23:20.760 11970-11970 MediaBrowserCompat                       D  Connecting to a MediaBrowserService.
2023-02-14 13:23:20.783 11970-11970 ExoPlayerImpl                            I  Init 7df60bd [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33]
2023-02-14 13:23:20.819 11970-11970 ExoPlayerImpl                            I  Release 7df60bd [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33] [media3.common, media3.exoplayer, media3.decoder, media3.datasource, media3.extractor]
2023-02-14 13:23:26.319 11970-11970 MediaBrowserCompat                       D  Connecting to a MediaBrowserService.
2023-02-14 13:23:26.345 11970-11970 ExoPlayerImpl                            I  Init 540e5f3 [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33]
2023-02-14 13:23:26.388 11970-11970 ExoPlayerImpl                            I  Release 540e5f3 [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33] [media3.common, media3.exoplayer, media3.decoder, media3.datasource, media3.extractor]
2023-02-14 13:23:27.001 11970-11970 MediaBrowserCompat                       D  Connecting to a MediaBrowserService.
2023-02-14 13:23:27.025 11970-11970 ExoPlayerImpl                            I  Init f1d97e0 [AndroidXMedia3/1.0.0-beta03] [redfin, Pixel 5, Google, 33]

I'm know ExoPlayer has a MediaSessionConnector but the documentation doesn't say to use it and there's little code examples on how to implement it.

This is a stripped down version of my MediaBrowserService code:

public class MediaPlayerService extends MediaBrowserServiceCompat {
    private ExoPlayer mPlayer;
    private MediaSessionCompat mMediaSessionCompat;
    
    @Override
    public void onCreate() {
        super.onCreate();

        mMediaSessionCompat = new MediaSessionCompat(this, MediaPlayerService.class.getSimpleName());
        mMediaSessionCompat.setCallback(mMediaSessionCallback);
        mMediaSessionCompat.setActive(true);

        mPlaybackBuilder = new PlaybackStateCompat.Builder();
        mPlaybackBuilder.setActions(
                        PlaybackStateCompat.ACTION_PLAY_PAUSE |
                                PlaybackStateCompat.ACTION_PLAY |
                                PlaybackStateCompat.ACTION_PAUSE |
                                PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS |
                                PlaybackStateCompat.ACTION_SKIP_TO_NEXT);
                                
        setSessionToken(mMediaSessionCompat.getSessionToken());

        mPlaybackAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                .build();

        mPlayer = new ExoPlayer.Builder(mContext).build();
        mPlayer.addListener(new PlayerEventListener());
    }
    
    private final MediaSessionCompat.Callback mMediaSessionCallback = new MediaSessionCompat.Callback() {
    
        @Override
        public void onStop() {
            super.onStop();

            StopAudio();
        }

        @Override
        public void onPlay() {
            super.onPlay();

            PlayAudio();
        }

        @Override
        public void onPause() {
            super.onPause();

            PauseAudio();
        }
    };

    
     private class PlayerEventListener implements Player.Listener {

        @Override
        public void onPlaybackStateChanged(int state) {
            if (state == Player.STATE_BUFFERING) {
  
            } else if (state == Player.STATE_READY) {


            } else if (state == Player.STATE_ENDED)
        }
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();

        mMediaSessionCompat.setMetadata(null);
        mMediaSessionCompat.setActive(false);
        mMediaSessionCompat.release();
        
        mPlayer.release();
    }
        
}

Solution

  • The clue is this part in the documentation:

    If Android can identify the last active media session, it tries to restart the session by sending an ACTION_MEDIA_BUTTON Intent to a manifest-registered component (such as a service or BroadcastReceiver).

    This means you need to override onMediaButtonEvent in the MediaSessionCompat.Callback and restart playback there:

    @Override
    public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
    
    KeyEvent keyEvent = (KeyEvent) mediaButtonEvent.getExtras().get(Intent.EXTRA_KEY_EVENT);
    
        if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY) {
        //restart playback
        }
    
        return super.onMediaButtonEvent(mediaButtonEvent);
    }