Using MediaSessionCompat
with MediaBrowserServiceCompat
. Suppose the service is not running. Now send a Media Button event, for example press the Next button on the headphones:
$ adb shell media dispatch next
And look at that! Not one but two Media Button events are being dispatched really! One is ACTION_DOWN
and the other is ACTION_UP
!
2020-12-16 00:29:29.627 11213-11213/? D/AndroidRuntime: Calling main entry com.android.commands.media.Media
2020-12-16 00:29:29.665 2056-2383/? D/MediaSessionService: Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_NEXT, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=8068837, downTime=8068837, deviceId=-1, source=0x101, displayId=-1 } to the last known PendingIntent PendingIntent{96b5217: PendingIntentRecord{6cc38aa com.example.mediaservicetest broadcastIntent}}
2020-12-16 00:29:29.666 2056-2383/? D/MediaSessionService: Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_NEXT, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=8068837, downTime=8068837, deviceId=-1, source=0x101, displayId=-1 } to the last known PendingIntent PendingIntent{96b5217: PendingIntentRecord{6cc38aa com.example.mediaservicetest broadcastIntent}}
The MediaButtonReceiver
is now binding MediaBrowserServiceCompat
to promptly execute the callback and then it's releasing it. The sequence is:
onCreate()
onBind()
onSkipToNext() - // 1st event only*
onUnbind()
onDestroy()
This is being called twice, really fast. So two instances of MediaBrowserServiceCompat
were created, used and destroyed quickly, in turn.
*Except, only the first one was actually used as Media Session callback. onSkipNext()
was only executed for ACTION_DOWN
as ACTION_UP
was filtered out by MediaSessionCompat
before calling the Callback!
2020-12-16 00:29:29.672 10917-10917/com.example.mediaservicetest D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2020-12-16 00:29:29.675 10917-10917/com.example.mediaservicetest I/main.MediaService.onCreate: *
2020-12-16 00:29:29.677 2056-2383/? D/MediaSessionService: Media button session is changed to com.example.mediaservicetest/foo (userId=0)
2020-12-16 00:29:29.686 10917-10917/com.example.mediaservicetest I/main.MediaService.onBind: *
2020-12-16 00:29:29.694 10917-10917/com.example.mediaservicetest I/main.MediaService$mediaSessionCallback.onSkipToNext: *
2020-12-16 00:29:29.695 10917-10917/com.example.mediaservicetest D/MediaBrowserCompat: Connecting to a MediaBrowserService.
2020-12-16 00:29:29.696 10917-10917/com.example.mediaservicetest I/main.MediaService.onUnbind: *
2020-12-16 00:29:29.696 10917-10917/com.example.mediaservicetest I/main.MediaService.onDestroy: *
2020-12-16 00:29:29.696 2056-2370/? D/MediaSessionService: Media button session is changed to null
2020-12-16 00:29:29.704 10917-10917/com.example.mediaservicetest I/main.MediaService.onCreate: *
2020-12-16 00:29:29.707 2056-2370/? D/MediaSessionService: Media button session is changed to com.example.mediaservicetest/foo (userId=0)
2020-12-16 00:29:29.734 10917-10917/com.example.mediaservicetest I/main.MediaService.onBind: *
2020-12-16 00:29:29.771 10917-10917/com.example.mediaservicetest I/main.MediaService.onUnbind: *
2020-12-16 00:29:29.771 10917-10917/com.example.mediaservicetest I/main.MediaService.onDestroy: *
2020-12-16 00:29:29.772 2056-2370/? D/MediaSessionService: Media button session is changed to null
Now for me it doesn't make much sense to instantiate this service twice (once for no reason). There is a MediaSessionCompat
created in there, along with other init stuff. This quick-fire create-drop-create again caused me some pain managing all the player, focus, receivers, callbacks, notifications and what not!
So is this as designed, or some bug of the library? Or am I using it wrong?
Maybe @ianhanniballake would be interested in this. I could not find any explanation anywhere else. Thanks!