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

audiolayers与audio_service被其他应用中断后状态显示异常求助

解决方案:处理音频焦点丢失后的状态同步问题

问题出在你的AudioHandler没有监听系统音频焦点的中断事件,导致其他应用抢占音频焦点后,本地的播放状态没有及时更新。以下是具体解决步骤:


1. 在自定义AudioHandler中监听音频焦点事件

在你的CustomAudioHandler里,通过AudioSession监听系统音频中断和焦点丢失事件,触发状态更新:

import 'package:audio_service/audio_service.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:audio_session/audio_session.dart';

class CustomAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
  final AudioPlayer _audioPlayer = AudioPlayer();
  late AudioSession _audioSession;

  CustomAudioHandler() {
    _initAudioSession();
    _syncPlayerStateToHandler();
  }

  Future<void> _initAudioSession() async {
    // 配置音频会话为音乐类型
    _audioSession = await AudioSession.instance;
    await _audioSession.configure(const AudioSessionConfiguration.music());

    // 监听"音频变得嘈杂"事件(比如其他应用开始播放)
    _audioSession.becomingNoisyEventStream.listen((_) => pause());

    // 监听音频中断事件
    _audioSession.interruptionEventStream.listen((event) {
      if (event.type == AudioInterruptionType.pause || 
          event.type == AudioInterruptionType.duck) {
        // 当系统暂停音频或降低音量时,同步更新状态
        pause();
      }
    });
  }

  // 同步AudioPlayer的状态到AudioHandler的playbackState流
  void _syncPlayerStateToHandler() {
    _audioPlayer.onPlayerStateChanged.listen((playerState) {
      final isPlaying = playerState == PlayerState.playing;
      playbackState.add(playbackState.value.copyWith(
        playing: isPlaying,
        processingState: isPlaying ? ProcessingState.ready : ProcessingState.idle,
      ));
    });
  }

  @override
  Future<void> pause() async {
    await _audioPlayer.pause();
    // 必须更新playbackState的playing状态,否则StreamBuilder收不到变化
    playbackState.add(playbackState.value.copyWith(playing: false));
  }

  // 确保play方法也正确更新状态
  @override
  Future<void> play() async {
    await _audioPlayer.play(/* 你的音频源 */);
    playbackState.add(playbackState.value.copyWith(playing: true));
  }
}

2. 移除不必要的生命周期监听

现在不需要在didChangeAppLifecycleState里手动查询状态了,因为AudioHandler的playbackState流会自动同步最新状态,你的StreamBuilder会自动刷新UI。


关键说明

  • 音频焦点的管理是系统层面的,必须通过AudioSession监听中断事件,才能在其他应用抢占焦点时及时更新本地状态。
  • 一定要保证AudioHandler的playbackState流实时同步AudioPlayer的状态,这样UI层的StreamBuilder才能拿到正确的播放状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:20:42