Flutter Audio_service通知栏点击暂停后按钮不更新为播放按钮问题
问题
在Android 11设备上使用Flutter的Audio_service包时遇到异常:
- Flutter UI里的播放/暂停按钮功能正常,但通知栏中除暂停按钮外的其他按钮都能正常响应
- 点击暂停按钮后,通知栏按钮无法更新:打印
playbackState.value.controls显示结果正确(已包含播放按钮配置),但通知栏仍显示暂停按钮,点击该按钮还是会执行暂停操作
相关代码片段:
@override Future<void> stop() async { print(playbackState.value.controls); playbackState.add(playbackState.value .copyWith(playing: false, controls: [MediaControl.skipToPrevious, MediaControl.play, MediaControl.skipToNext])); await player?.stop(); print(playbackState.value.controls); } @override Future<void> seek(Duration position) async { player?.seek(position); print(playbackState.value.controls); } @override Future<void> play() async { if (player == null) { if (curindex != null) { playnew(curindex!); } } else { playbackState.add(playbackState.value.copyWith( playing: true, controls: [MediaControl.skipToPrevious, MediaControl.pause, MediaControl.skipToNext, MediaControl.stop], )); await player?.play(); } } @override Future<void> pause() async { playbackState.add(playbackState.value.copyWith( playing: false, controls: [MediaControl.skipToPrevious, MediaControl.play, MediaControl.skipToNext], )); await player?.pause(); }
解决方案
1. 调整状态更新与播放器操作的顺序
Android 11对通知状态的同步时机敏感,需先完成playbackState的更新,再执行播放器的暂停/播放操作,确保平台端能及时接收状态变化:
修改pause()和play()方法:
@override Future<void> pause() async { // 先更新播放状态与控制按钮 await playbackState.add(playbackState.value.copyWith( playing: false, controls: [MediaControl.skipToPrevious, MediaControl.play, MediaControl.skipToNext], )); // 再执行播放器暂停 await player?.pause(); } @override Future<void> play() async { if (player == null) { if (curindex != null) { playnew(curindex!); } } else { // 先更新播放状态与控制按钮 await playbackState.add(playbackState.value.copyWith( playing: true, controls: [MediaControl.skipToPrevious, MediaControl.pause, MediaControl.skipToNext, MediaControl.stop], )); // 再执行播放器播放 await player?.play(); } }
2. 确保状态字段严格匹配
每次更新playbackState时,playing布尔值必须和控制按钮完全对应:
- 播放状态:
playing: true+ 包含MediaControl.pause - 暂停状态:
playing: false+ 包含MediaControl.play
避免出现状态值与按钮配置不匹配的情况,导致通知栏无法正确渲染。
3. 强制触发通知刷新(针对旧版本audio_service)
如果使用的是audio_service v0.x系列版本,在更新playbackState后可手动调用通知刷新方法:
// 在playbackState.add之后添加 await AudioService.updateNotification();
v1.x及以上版本无需手动调用,只需确保playbackState流的更新逻辑正确,没有被其他代码覆盖。
4. 同步播放器实际状态与AudioService状态
检查播放器的实际播放状态(如player.playing)是否与playbackState中的playing字段完全一致,避免因状态不一致导致通知栏控件不更新。
内容的提问来源于stack exchange,提问作者MYB
相关产品推荐
相关产品推荐

