0

How can I manually handle media button actions with Media3 in a peaceful and compatible way without using MediaSessionConnector?

Previously, I used to handle media button commands using MediaSessionConnector and MediaSessionCompat, but due to Android 13 changes, I migrated to Media3 and removed the MediaSessionConnector, here is what I had before:

mediaSessionConnector.setMediaButtonEventHandler { player, mediaButtonEvent ->
                
                val event: KeyEvent? = mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)
                when (event?.keyCode) {
                    KeyEvent.KEYCODE_MEDIA_NEXT -> {
                        if (event.action == KeyEvent.ACTION_UP) {
                            nextSegment()
                        }
                        true
                    }
                    KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
                        if (event.action == KeyEvent.ACTION_UP) {
                            previousSegment()
                        }
                        true
                    }
                    KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
                        if (event.action == KeyEvent.ACTION_UP) {
                            onPlayPause()
                        }
                        true
                    }
                    else -> false
                }
            }

as you see I have some custom behaviors for backward and forward action to handle back and forth segments in our application. but recently due to android 13 changes I went through the migration guide (from exo to media3) and removed the media session connector but I can no longer handle the media button receiver manually.

Even I tried to register my own button receiver with android.intent.action.MEDIA_BUTTON action but still is not triggering that. then I checked the MediaSession (from media3) implementation and found out it register a MediaButtonReceive itself with the same action with below implementation which overrides mine and it only works for play/pause, (what I am looking for is double tap for fast-forward action while I need my customize functioning to go to next segment), :

here is google MediaButtonReceive:

private final class MediaButtonReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
      if (!Util.areEqual(intent.getAction(), Intent.ACTION_MEDIA_BUTTON)) {
        return;
      }
      Uri sessionUri = intent.getData();
      if (!Util.areEqual(sessionUri, sessionUri)) {
        return;
      }
      KeyEvent keyEvent = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
      if (keyEvent == null) {
        return;
      }
      getSessionCompat().getController().dispatchMediaButtonEvent(keyEvent);
    }
  }

what I understand so far the MediaSession has an internal package private mediaSessionCompat which is used for some part of logic like dispatchMediaEvent.

------ a workaround which didn't work-----

I also attempted a workaround by defining MediaSessionCompat again alongside the actual MediaSession and setting a callback for it and override onMediaButtonEvent but it's not triggering that callback.

here is how I defined that:

  mediaSessionCompat = MediaSessionCompat(applicationContext, MEDIA_SESSION_TAG)
  mediaSessionCompat?.setSessionActivity(mediaSession?.sessionActivity)
  mediaSessionCompat?.setCallback{
       override fun onMediaButtonEvent(mediaButtonEvent: Intent?): Boolean {..}
  }

Is there any other peaceful and compatible way to handle media button actions manually in media3? Any insights or alternative approaches would be appreciated.

imansdn
  • 968
  • 1
  • 7
  • 17

0 Answers0