Yoann Far
Yoann Far

Reputation: 322

Best way to update seekbar in activity from a MediaBrowserService?

So I have a MediaBrowserServiceCompat() to play some audios with MediaPlayer, and one activity with the UI interface of the current media playing. On this interface I have a progress bar that I would like to update with the current position of the media player.

enter image description here

I was thinking about having this kind of method in the service, where every second I would send the current position of the MediaPlayer through metadata of the MediaSession :

 private fun updateTimerMetadata() {
    thread {
        Thread.sleep(1000)
        if (mp?.isPlaying == true) {
            mediaSession.setMetadata(
                MediaMetadataCompat.Builder()
                    .putLong("timerUpdate", mp?.currentPosition!!.toLong())
                    .build()
            )
            updateTimerMetadata()
        }
    }
}

I would receive it in the activity in the onMetadataChanged() and then update the UI.

But then I thought I could just start a timer in the activity and manage it when it's play/pause, and then no need to communicate with the service for that. But maybe it would be a risk for the bar to be unsync with the mediaplayer...

So I would like to know what's the best appraoch to handle this problem?

To communicate between the service and the activity, I use a MediaSession in the service :

   mediaSession = MediaSessionCompat(baseContext, SERVICE_TAG).apply {
        // Enable callbacks from MediaButtons and TransportControls
        setFlags(
            MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
                    or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
        )
        // Set an initial PlaybackState with ACTION_PLAY, so media buttons can start the player
        stateBuilder = PlaybackStateCompat.Builder()
            .setActions(
                PlaybackStateCompat.ACTION_PLAY
                        or PlaybackStateCompat.ACTION_PLAY_PAUSE
            )
        setPlaybackState(stateBuilder.build())
        setSessionToken(sessionToken)
    }

And a MediaController in the activity to call mediaController.transportControls for the actions of the buttons.

Upvotes: 0

Views: 878

Answers (1)

Yoann Far
Yoann Far

Reputation: 322

I found an other way which I think may be better.

You can save the position of the media player in the playback state

val stateBuilder = PlaybackStateCompat.Builder()
    stateBuilder.setState(
        playPauseState,
        mp?.currentPosition?.toLong() ?: PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN,
        1F
    )
    mediaSession.setPlaybackState(stateBuilder.build())

And then in the activity, you can get it this way:

val timerPosition = mediaController.playbackState.position

Upvotes: 1

Related Questions