media icon indicating copy to clipboard operation
media copied to clipboard

Error in RuntimeException while executing runnable PlayerServiceActivity$$ExternalSyntheticLambda0@a30fc82 with executor MoreExecutors.directExecutor()

Open anshuhexabrain opened this issue 1 year ago • 1 comments

Hello there, First off, I want to say a big thank you for the amazing work on Media3! 🎉 The integration process was really smooth, and I'm super impressed.

I have a query regarding crash issue in MediaLibraryService

I have a implemented MediaLibraryService for mobile and android auto and getting an crash while opening the activity like

RuntimeException while executing runnable AudioWithSyncServiceActivity$$ExternalSyntheticLambda0@a30fc82 with executor MoreExecutors.directExecutor() java.util.concurrent.ExecutionException: java.lang.SecurityException: Session rejected the connection request. at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:594) at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:553)

As I have added below code for my activity and service

Activity ` private lateinit var controllerFuture: ListenableFuture<MediaController> private val controller: MediaController? get() = if (controllerFuture.isDone && !controllerFuture.isCancelled) controllerFuture.get() else null

    controllerFuture =
            MediaController.Builder(
                this,
                SessionToken(this, ComponentName(this, PlayerServiceWithSync::class.java)),
            )
                .buildAsync()
        controllerFuture.addListener({ setController() }, MoreExecutors.directExecutor())
        
        private fun setController() {
    val controller = this.controller ?: return

    playerView.player = controller
    playerView.useController = true

    lifecycleScope.launch {
        delay(500)
        EventBus.getDefault().post(MessageEvent(controller))
    }
    
    override fun onBackPressed() {
    releaseService()
    super.onBackPressed()
}

private fun releaseService(){
    Log.d(TAG, "Release service called")
    playerView.player?.release()
    playerView.player = null
    releaseController()
    val stopIntent = Intent(this, PlayerServiceWithSync::class.java)
    stopIntent.action = "STOP_SERVICE"
    startService(stopIntent)
}

private fun releaseController() {
    if (::controllerFuture.isInitialized){
        MediaController.releaseFuture(controllerFuture)
    }
}

}
                                                                                     	

onService class

OnCreate

val activityClass = msActivity?.get()
            if (activityClass != null){
                val intent = Intent(this@PlayerServiceWithSync, activityClass!!::class.java)
                val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                } else {
                    PendingIntent.FLAG_UPDATE_CURRENT
                }
                val pendingIntent = PendingIntent.getActivity(
                    this@PlayerServiceWithSync, 0, intent, pendingFlags
                )

                mediaLibrarySession = if (pendingIntent != null){
                    MediaLibrarySession.Builder(this, getMsPlayer()?.msPlayer!!, callback)
                        .setSessionActivity(pendingIntent)
                        .setCustomLayout(createCustomLayout())
                        .build()
                } else {
                    MediaLibrarySession.Builder(this, getMsPlayer()?.msPlayer!!, callback)
                        .setCustomLayout(createCustomLayout())
                        .build()
                }
            } else {
                MediaLibrarySession.Builder(this, getMsPlayer()?.msPlayer!!, callback)
                    .setCustomLayout(createCustomLayout())
                    .build()
            }

@Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: MessageEvent) {

        val player = if (msPlayer?.get() != null){
            msPlayer?.get()
        } else {
            val config = PlayerConfig()

            val msPlayer = WeakReference(Player(
                msContext?.get() ?: this,
                msConfig ?: config,
                msContainer?.get(),
                msPlayerView?.get()?: PlayerView(this),
                msMiniPlayerConfig ?: MiniPlayerConfig()
            ))
            msPlayer.get()
        }

//        msConfig?.let { msPlayer?.get()?.updateMsConfig(config = it) }
        player?.setPlayer(event.controller)
//        playerLitener()
    }
as I am using media3 1.4.0

anshuhexabrain avatar Aug 05 '24 05:08 anshuhexabrain

@AnshumanHexabrain

I think there is some confusion in your code logic. It appears that you are creating the controller and then sending it via MessageEvent to your session service code of which you are then setting the controller as the player? The session code should have its own ExoPlayer instance that will be running the media playback. It should not be the controller.

Perhaps it would help to review the developer documentation we have, https://developer.android.com/media/implement/playback-app.

All you should need to do is set the correct token on the building of your MediaController. You shouldn't need to pass the controller to the session code.

Here is some other resources and code that may be helpful.

Hopefully that helps! Please write back if you have additional questions.

microkatz avatar Aug 06 '24 15:08 microkatz