0

所以我有一个 MediaBrowserServiceCompat() 来使用 MediaPlayer 播放一些音频,以及一个使用当前媒体播放的 UI 界面的活动。在这个界面上,我有一个进度条,我想用媒体播放器的当前位置进行更新。

在此处输入图像描述

我正在考虑在服务中使用这种方法,每秒我都会通过 MediaSession 的元数据发送 MediaPlayer 的当前位置:

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

我会在 onMetadataChanged() 的活动中收到它,然后更新 UI。

但是后来我想我可以在活动中启动一个计时器并在它播放/暂停时对其进行管理,然后无需为此与服务进行通信。但也许酒吧与媒体播放器不同步会有风险......

所以我想知道处理这个问题的最佳方法是什么?

为了在服务和活动之间进行通信,我在服务中使用了 MediaSession:

   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)
    }

并且活动中的 MediaController 调用 mediaController.transportControls 来执行按钮的操作。

4

1 回答 1

1

我发现了另一种我认为可能更好的方法。

可以保存播放状态下媒体播放器的位置

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

然后在活动中,可以这样获取:

val timerPosition = mediaController.playbackState.position
于 2020-12-23T18:25:31.620 回答