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.