Chromecast跨设备控制异常:MediaIntentReceiver未接收同网设备播放/暂停Intent
我们使用Chromecast Android SDK投放视频,自行实现了RemoteMediaClient的play()、pause()、seek(Long)功能,并通过CastMediaOptions配置了投放设备的通知,同时设置MediaIntentReceiver监听通知控制事件。目前本地设备通过通知控制播放/暂停时,Receiver能正常回调,但同一WiFi下其他设备控制时,MediaIntentReceiver无法收到Intent,导致应用内播放器状态无法同步更新。
问题根源
MediaIntentReceiver的设计仅针对本地设备通过通知发起的控制指令,当其他设备通过同一网络控制Chromecast时,控制指令是直接发送到Chromecast Receiver端,再由Receiver将最新的媒体状态同步到所有连接的Sender设备,这个同步过程不会触发本地设备的MediaIntentReceiver回调。
解决方案:监听RemoteMediaClient的媒体状态变化
要统一处理本地和跨设备的控制事件,需要通过RemoteMediaClient的MediaStatusListener监听媒体状态的全局变化,无论控制指令来自本地还是其他设备,只要Chromecast的媒体状态更新,都会触发该回调。
实现步骤
- 获取活跃的
CastSession,并获取对应的RemoteMediaClient - 注册
MediaStatusListener,在onMediaStatusUpdated回调中处理状态更新 - 会话销毁时注销监听,避免内存泄漏
代码示例
// 在CastSession建立成功后注册监听(比如在SessionManagerListener的onSessionStarted回调中) val castSession = CastContext.getInstance(context).sessionManager.currentCastSession castSession?.remoteMediaClient?.let { remoteMediaClient -> val mediaStatusListener = object : RemoteMediaClient.MediaStatusListener { override fun onMediaStatusUpdated(mediaStatus: MediaStatus) { // 获取当前播放状态 val isPlaying = mediaStatus.isPlaying val currentPosition = mediaStatus.currentPosition // 向活跃页面发送事件,更新本地播放器状态 // 示例:通过EventBus或ViewModel发送状态更新 } } // 注册监听 remoteMediaClient.registerMediaStatusListener(mediaStatusListener) // 记得在会话结束时注销监听 // 可在SessionManagerListener的onSessionEnded回调中执行: // remoteMediaClient.unregisterMediaStatusListener(mediaStatusListener) }
保留原有MediaIntentReceiver的作用
原有的FitbuddMediaIntentReceiver仍需保留,用于处理本地设备点击通知控件的场景(比如用户直接点击手机上的Chromecast通知按钮),此时仍会触发onReceiveActionTogglePlayback等回调,可在这些回调中调用RemoteMediaClient的对应方法,并通过上述MediaStatusListener同步状态。
内容的提问来源于stack exchange,提问作者P Vartak

