1

I've tried to scope down the code as much as possible to identify the problem (although may have missed some pieces) but essentially I'm having an issue that occurs for Android 11 or higher where the MediaBrowserServiceCompat doesn't get destroyed using the same code that will destroy it in other versions. I've narrowed it down to a notification and setting the MediaSession Token. If I set it, it won't destroy when calling stopSelf() if I don't set it, it will clear. I've also noticed that it will bind to the service (if MediaSession Token is set), but I see no way to force it to unbind. Example code provided below

class MediaPlayerService : MediaBrowserServiceCompat()  {
    private val mediaSession by lazy { MediaSessionCompat(this, "MusicService") }
    private val mediaPlayerNotification by lazy { MediaPlayerNotification(this) }
    
    override fun onCreate() {
        super.onCreate()
        sessionToken = mediaSession.sessionToken
    }

    //Not called on Android 11
    override fun onDestroy() {
        super.onDestroy()
    }
    
    playerStarted(){
        mediaPlayerNotification.createNotification()
    }


    fun playerStopped() {
        stopSelf()
    }

}



const val mId = 101

class MediaPlayerNotification(service: MediaPlayerService) : BroadcastReceiver() {
    private val notificationManager: NotificationManager = service.getSystemService(context.NOTIFICATION_SERVICE) as NotificationManager
    private val notificationBuilder by lazy {
        val filter = IntentFilter()
        filter.addAction(NOTIFICATION_ACTION_SKIP)
        service.registerReceiver(this, filter)


        NotificationCompat.Builder(service, MEDIA_PLAYER_CHANNEL)
                .setStyle(androidx.media.app.NotificationCompat.MediaStyle()
                        .setShowActionsInCompactView(0)
                        .setMediaSession(service.sessionToken))// If I comment this line, the service will destory when `stopSelf()` is called 
                .setSmallIcon(R.drawable.img_logo_white)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) // Show controls on lock screen even when user hides sensitive content.
                .addAction(skipAction)
    }

    private var notification = notificationBuilder.build()

    fun createNotification() {
        notification = notificationBuilder
                .setContentTitle("title")
                .setContentText("text")
                .build()
        notificationManager.notify(mId, notification)
    }

}


How can I clarify to the notification that the mediaSession has ended so that it unbinds from the service (I believe this is the path I need to go down). I also can't seem to find any Android documentation on what changed and why this broke on Android 10

Arst
  • 3,098
  • 1
  • 35
  • 42
Nic Capdevila
  • 1,495
  • 14
  • 27
  • I have exact the same problem. Calling `stopSelf` will not trigger `onDestroy`. The only closest answer I can find is to call `stopForeground(true)` before `stopSelf` because I called `startForeground` for notification. That will stop the music, but the service's `onDestroy ` dose not get called still. – Arst Feb 15 '22 at 11:39
  • I noticed that if use setMediaSession there is a `onBind` event triggered. The intent `[onBind] Intent { act=android.media.browse.MediaBrowserService cmp=app.myapp.PlaybackService }`. That explains why the onDestroy is not called. – Arst Feb 15 '22 at 13:27

0 Answers0