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

Flutter中audio_service通知无标题及进度显示问题求助

问题修复方案

1. 通知标题不显示的原因及修复

通知的标题等媒体信息来自当前的mediaItem,你当前只更新了队列但未设置当前播放的媒体项,同时队列的更新方式也不正确:

  • queue是ValueNotifier<List<MediaItem>>,不能直接调用add方法,需更新它的value属性
  • 必须通过mediaItem.add()将当前播放的MediaItem传递给audio_service,通知才能获取到标题等信息

修改addd方法:

void addd(){
  // 创建目标媒体项
  final targetItem = const MediaItem(id: "dd", title: "ss", duration: Duration(seconds: 40));
  // 正确更新队列
  queue.value = [targetItem];
  // 设置当前播放的媒体项,供通知读取标题信息
  mediaItem.add(targetItem);
  playbackState.add(
    PlaybackState(
      queueIndex: 0,
      playing: true,
      processingState: AudioProcessingState.loading,
      // 初始化进度为0
      currentPosition: Duration.zero,
    )
  );
}

2. 音频进度不显示的原因及修复

通知进度依赖playbackState中的currentPosition,你需要定期更新该值模拟播放进度,同时注意播放状态下的控件设置错误:

  • 播放状态下,控件应显示MediaControl.pause而非MediaControl.play
  • 需用定时器定期更新currentPosition,模拟音频播放的进度推进

修改play方法,并添加定时器维护进度:

Timer? _progressTimer;
Duration _currentPosition = Duration.zero;

@override
Future<void> play()async {
  final currentItem = mediaItem.value;
  if (currentItem == null) return;
  
  // 重置进度
  _currentPosition = Duration.zero;
  // 取消之前的定时器,避免重复触发
  _progressTimer?.cancel();
  // 每秒更新一次进度
  _progressTimer = Timer.periodic(Duration(seconds: 1), (timer) {
    _currentPosition += Duration(seconds: 1);
    // 防止进度超过媒体总时长
    if (_currentPosition >= currentItem.duration!) {
      timer.cancel();
      _currentPosition = currentItem.duration!;
    }
    // 更新播放状态,同步最新进度
    playbackState.add(
      playbackState.value.copyWith(
        currentPosition: _currentPosition,
      )
    );
  });

  playbackState.add(
    playbackState.value.copyWith(
      processingState: AudioProcessingState.ready,
      playing: true,
      // 播放状态显示暂停控件
      controls: [MediaControl.pause],
      // 声明支持的操作,确保进度条可交互(按需设置)
      actions: {MediaAction.seek, MediaAction.pause, MediaAction.play},
    )
  );
  dev.log("playing");
}

// 在暂停和停止时取消定时器,避免资源浪费
@override
Future<void> pause() async {
  _progressTimer?.cancel();
  playbackState.add(playbackState.value.copyWith(
    playing: false,
    controls: [MediaControl.play],
  ));
  dev.log("pause is called");
}

@override
Future<void> stop() async {
  _progressTimer?.cancel();
  _currentPosition = Duration.zero;
  playbackState.add(playbackState.value.copyWith(
    playing: false,
    processingState: AudioProcessingState.idle,
  ));
  dev.log("stop is called");
}

3. 额外注意事项

  • 确保初始化AudioHandler时,已正确配置通知通道参数(如AudioService.init中的notificationChannelId)
  • 建议在真机上测试,模拟器的通知可能存在延迟或显示异常

内容的提问来源于stack exchange,提问作者kamal douma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 00:22:16