You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 10:25:17