Search code examples
androidandroid-mediaplayerexoplayerandroid-mediasession

Can updating an Activity from MediaBrowserService cause the Service to crash?


I have an audio app with a MediaBrowserService. To update the SeekBar in the Activity, I have a Runnable in the service that updates the MediaSession extras every 250 milliseconds (this is to ensure the SeekBar movement isn't janky).

Everything works fine except a small number of users are reporting that after a couple of minutes the playback consistently cuts out. The logs don't show that onDestroy or onPause or onStop of the MediaSessionCompat.Callback is called or any of the error handling. It just stops. However, I'm unable to recreate it myself. Once the audio starts there is nothing running in the service but this. Is it possible updating the SeekBar this way is causing the playback to stop?

public class MediaPlayerService extends MediaBrowserServiceCompat {

    private Handler mMediaHandler;
    private MediaSessionCompat mMediaSessionCompat;
    private ExoPlayer player;

    @Override
    public void onCreate() {
        super.onCreate();
        
        mMediaSessionCompat = new MediaSessionCompat(this, MediaPlayerService.class.getSimpleName());
        mMediaSessionCompat.setCallback(mMediaSessionCallback);
    }
        
    public void PlayAudio()
    {
        player = new ExoPlayer.Builder(this).build();
        player.setMediaItem(MediaItem.fromUri(uri), position);
        player.prepare();
        player.play();
        
        mMediaHandler = new Handler(Looper.getMainLooper());
        mMediaHandler.post(mUpdateMediaPosition);
    }
        
    Runnable mUpdateMediaPosition = new Runnable() {
        public void run() {

            final Bundle extras = new Bundle();
            extras.putInt("position", player.getCurrentPosition());
            mMediaSessionCompat.setExtras(extras);

            mMediaHandler.postDelayed(this, 250);
        }
    };
}

public class MediaActivity 
{
    private MediaBrowserCompat mMediaBrowserCompat;
    private MediaControllerCompat mMediaController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
          mMediaBrowserCompat = new MediaBrowserCompat(
                                getApplicationContext(),
                                new ComponentName(mContext, MediaPlayerService.class),
                                mMediaBrowserCompatConnectionCallback,
                                getIntent().getExtras());
                        mMediaBrowserCompat.connect();
    }

    MediaControllerCompat.Callback mMediaControllerCompatCallback = new MediaControllerCompat.Callback() {
        @Override
        public void onExtrasChanged(Bundle extras) {
            super.onExtrasChanged(extras);

            int position = extras.getInt("position");

            seekBar.setProgress(position);
        }
        
    }

    MediaBrowserCompat.ConnectionCallback mMediaBrowserCompatConnectionCallback = new MediaBrowserCompat.ConnectionCallback() {

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

            mMediaController = new MediaControllerCompat(mContext, mMediaBrowserCompat.getSessionToken());
            mMediaController.registerCallback(mMediaControllerCompatCallback);
        }
    };

}

Solution

  • Answering my own question in case it helps anyone in the future but connecting to a MediaBrowserService does not actually start the service. You have to call startService in the MediaBrowserService (the documentation recommends when playback starts) or the MediaBrowserService will stop when all connections to it disconnect.