Error in ANDROID NATIVE JETPACK COMPOSE app using MEDIA3 functionality

45 views Asked by At

I have been getting the following error log for my code which has been hosted at this repository GITHUB LINK

FATAL EXCEPTION: main
                                                                                                  Process: com.aarav.shesaswiftieee, PID: 14300
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:562)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 
Caused by: java.util.concurrent.ExecutionException: java.lang.SecurityException: Session rejected the connection request.
    at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:588)
    at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:547)
    at com.aarav.shesaswiftieee.player.service.MusicPlaybackController.getMediaController(MusicPlaybackController.kt:25)
    at com.aarav.shesaswiftieee.player.service.MusicPlaybackController.controllerListener(MusicPlaybackController.kt:46)
    at com.aarav.shesaswiftieee.player.service.MusicPlaybackController._init_$lambda$0(MusicPlaybackController.kt:42)
    at com.aarav.shesaswiftieee.player.service.MusicPlaybackController.$r8$lambda$FF1CSXulRYlFH84wuKs76FsdpeE(Unknown Source:0)
    at com.aarav.shesaswiftieee.player.service.MusicPlaybackController$$ExternalSyntheticLambda0.run(Unknown Source:2)
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1270)
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:1038)
    at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:808)
    at androidx.media3.session.MediaControllerHolder.maybeSetException(MediaControllerHolder.java:67)
    at androidx.media3.session.MediaControllerHolder.onRejected(MediaControllerHolder.java:57)
    at androidx.media3.session.MediaController.release(MediaController.java:530)
    at androidx.media3.session.MediaControllerImplBase$$ExternalSyntheticLambda41.run(Unknown Source:2)
    at androidx.media3.common.util.Util.postOrRun(Util.java:752)
    at androidx.media3.session.MediaController.runOnApplicationLooper(MediaController.java:1926)
    at androidx.media3.session.MediaControllerStub.lambda$onDisconnected$1(MediaControllerStub.java:96)
    at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda4.run(Unknown Source:0)
    at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$12(MediaControllerStub.java:310)
    at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda13.run(Unknown Source:4)
    at androidx.media3.common.util.Util.postOrRun(Util.java:752)
    at androidx.media3.session.MediaControllerStub.dispatchControllerTaskOnHandler(MediaControllerStub.java:302)
    at androidx.media3.session.MediaControllerStub.onDisconnected(MediaControllerStub.java:94)
    at androidx.media3.session.MediaSessionService$MediaSessionServiceStub.lambda$connect$0$androidx-media3-session-MediaSessionService$MediaSessionServiceStub(MediaSessionService.java:729)
    at androidx.media3.session.MediaSessionService$MediaSessionServiceStub$$ExternalSyntheticLambda0.run(Unknown Source:10)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8177)
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 
Caused by: java.lang.SecurityException: Session rejected the connection request.
    at androidx.media3.session.MediaControllerHolder.maybeSetException(MediaControllerHolder.java:67) 
    at androidx.media3.session.MediaControllerHolder.onRejected(MediaControllerHolder.java:57) 
    at androidx.media3.session.MediaController.release(MediaController.java:530) 
    at androidx.media3.session.MediaControllerImplBase$$ExternalSyntheticLambda41.run(Unknown Source:2) 
    at androidx.media3.common.util.Util.postOrRun(Util.java:752) 
    at androidx.media3.session.MediaController.runOnApplicationLooper(MediaController.java:1926) 
    at androidx.media3.session.MediaControllerStub.lambda$onDisconnected$1(MediaControllerStub.java:96) 
    at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda4.run(Unknown Source:0) 
    at androidx.media3.session.MediaControllerStub.lambda$dispatchControllerTaskOnHandler$12(MediaControllerStub.java:310) 
    at androidx.media3.session.MediaControllerStub$$ExternalSyntheticLambda13.run(Unknown Source:4) 
    at androidx.media3.common.util.Util.postOrRun(Util.java:752) 
    at androidx.media3.session.MediaControllerStub.dispatchControllerTaskOnHandler(MediaControllerStub.java:302) 
    at androidx.media3.session.MediaControllerStub.onDisconnected(MediaControllerStub.java:94) 
    at androidx.media3.session.MediaSessionService$MediaSessionServiceStub.lambda$connect$0$androidx-media3-session-MediaSessionService$MediaSessionServiceStub(MediaSessionService.java:729) 
    at androidx.media3.session.MediaSessionService$MediaSessionServiceStub$$ExternalSyntheticLambda0.run(Unknown Source:10) 
    at android.os.Handler.handleCallback(Handler.java:958) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loopOnce(Looper.java:205) 
    at android.os.Looper.loop(Looper.java:294) 
    at android.app.ActivityThread.main(ActivityThread.java:8177) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 

This is my MusicPlaybackController class where I believe the crash takes place :

package com.aarav.shesaswiftieee.player.service

import android.content.ComponentName
import android.content.Context
import android.net.Uri
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import com.aarav.shesaswiftieee.data.PlayerState
import com.aarav.shesaswiftieee.data.SWIFT
import com.aarav.shesaswiftieee.data.toMusic
import com.aarav.shesaswiftieee.player.controller.PlaybackController
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import javax.inject.Inject

class MusicPlaybackController @Inject constructor(context: Context) : PlaybackController {


    private var mediaControllerFuture: ListenableFuture<MediaController>

    private val mediaController: MediaController?
        get() = if (mediaControllerFuture.isDone) mediaControllerFuture.get() else null


    override var mediaControllerCallback: ((
        playerState: PlayerState,
        currentMusic: SWIFT?,
        currentPosition: Long,
        totalDuration: Long,
        isShuffleEnabled: Boolean,
        isRepeatOneEnabled: Boolean
    ) -> Unit)? =
        null

    init {
        val sessionToken =
            SessionToken(context, ComponentName(context, MusicPlaybackService::class.java))
        mediaControllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
        mediaControllerFuture.addListener({ controllerListener() }, MoreExecutors.directExecutor())
    }

    private fun controllerListener() {
        mediaController?.addListener(object : Player.Listener {
            override fun onEvents(player: Player, events: Player.Events) {
                super.onEvents(player, events)
                with(player) {
                    mediaControllerCallback?.invoke(
                        playbackState.toPlayerState(isPlaying),
                        currentMediaItem?.toMusic(),
                        currentPosition.coerceAtLeast(0L),
                        duration.coerceAtLeast(0L),
                        shuffleModeEnabled,
                        repeatMode == Player.REPEAT_MODE_ONE
                    )
                }
            }
        })
    }

    private fun Int.toPlayerState(isPlaying: Boolean) =
        when (this) {
            Player.STATE_IDLE -> PlayerState.STOPPED
            Player.STATE_ENDED -> PlayerState.STOPPED
            else -> if (isPlaying) PlayerState.PLAYING else PlayerState.PAUSED
        }

    override fun addMediaItems(musics: List<SWIFT>) {
        val mediaItems = musics.map {
            MediaItem.Builder().setMediaId(it.songURL.toString()).setUri(it.songURL)
                .setMediaMetadata(
                    MediaMetadata.Builder()
                        .setTitle(it.title)
                        .setArtist(it.singer)
                        .setArtworkUri(Uri.parse(it.imageURL))
                        .setAlbumTitle(it.album)
                        .setTrackNumber(it.mediaID?.toInt())
                        .build()
                )
                .build()
        }
        mediaController?.setMediaItems(mediaItems)
    }

    override fun play(mediaItemIndex: Int) {
        mediaController?.apply {
            seekToDefaultPosition(mediaItemIndex)
            playWhenReady = true
            prepare()
        }
    }

    override fun resume() {
        mediaController?.play()
    }

    override fun pause() {
        mediaController?.pause()
    }

    override fun seekTo(position: Long) {
        mediaController?.seekTo(position)
    }

    override fun skipNext() {
        mediaController?.seekToNext()
    }

    override fun skipPrevious() {
        mediaController?.seekToPrevious()
    }

    override fun setShuffleModeEnabled(isEnabled: Boolean) {
        mediaController?.shuffleModeEnabled = isEnabled
    }

    override fun setRepeatOneEnabled(isEnabled: Boolean) {
        mediaController?.repeatMode = if (isEnabled) {
            Player.REPEAT_MODE_ONE
        } else {
            Player.REPEAT_MODE_OFF
        }
    }

    override fun getCurrentPosition(): Long = mediaController?.currentPosition ?: 0L

    override fun destroy() {
        MediaController.releaseFuture(mediaControllerFuture)
        mediaControllerCallback = null
    }
}

here's the MusicPlaybackService class:

package com.aarav.shesaswiftieee.player.service

import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture

class MusicPlaybackService : MediaSessionService() {

    private var mediaSession: MediaSession? = null
    private lateinit var exoPlayer: ExoPlayer

    private val audioAttributes =
        AudioAttributes.Builder().setContentType(C.AUDIO_CONTENT_TYPE_MUSIC).setUsage(C.USAGE_MEDIA)
            .build()

    override fun onCreate() {
        super.onCreate()
        exoPlayer = ExoPlayer.Builder(this)
            .setAudioAttributes(audioAttributes, true)
            .setHandleAudioBecomingNoisy(true).build()

        mediaSession = MediaSession.Builder(this, exoPlayer)
            .setCallback(MediaSessionCallback())
            .build()
    }


    override fun onDestroy() {
        mediaSession?.run {
            exoPlayer.release()
            release()
            mediaSession = null
        }

        super.onDestroy()
    }


    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = null

    private inner class MediaSessionCallback : MediaSession.Callback {
        override fun onAddMediaItems(
            mediaSession: MediaSession,
            controller: MediaSession.ControllerInfo,
            mediaItems: MutableList<MediaItem>
        ): ListenableFuture<MutableList<MediaItem>> {

            val updatedMediaItems = mediaItems.map {
                it.buildUpon().setUri(it.mediaId).build()
            }.toMutableList()

            return Futures.immediateFuture(updatedMediaItems)
        }
    }
}

and here's the PlaybackController interface:

package com.aarav.shesaswiftieee.player.controller

import com.aarav.shesaswiftieee.data.PlayerState
import com.aarav.shesaswiftieee.data.SWIFT

interface PlaybackController {
    var mediaControllerCallback: ((
        playerState: PlayerState, currentMusic: SWIFT?, currentPosition: Long, totalDuration: Long, isShuffleEnabled: Boolean, isRepeatOneEnabled: Boolean
    ) -> Unit)?


    fun addMediaItems(musics: List<SWIFT>)
    fun play(mediaItemIndex: Int)
    fun resume()
    fun pause()
    fun seekTo(position: Long)
    fun skipNext()
    fun skipPrevious()
    fun setShuffleModeEnabled(isEnabled:Boolean)
    fun setRepeatOneEnabled(isEnabled:Boolean)
    fun getCurrentPosition():Long
    fun destroy()
}

I have tried going through the documentation and trying to analyze and solve the crash with all the wit I have remaining since the past three months, It would be really really helpful if someone could help me out with this.

0

There are 0 answers