AVAudioSessionCategoryOptions.mixWithOthers首次播放音频暂停背景音乐问题
解决首次播放音效暂停背景音乐的问题
核心问题分析
首次激活音频会话时,系统会默认抢占音频焦点,导致背景音乐暂停;后续重新播放背景音乐后,焦点状态已处于共享模式,因此不会再触发暂停。需要针对iOS和Android的音频会话配置及激活时机做调整。
具体调整方案
Android端焦点类型修正
将androidAudioFocusGainType从AndroidAudioFocusGainType.gain改为AndroidAudioFocusGainType.gainTransientMayDuck(若不需要压低背景音乐,可尝试gainTransient)。gain是永久获取焦点的类型,会强制暂停其他音频,而短暂焦点类型更适合计时器这类临时音效的场景。iOS端激活时机调整
不要在初始化阶段就调用session.setActive(true),而是延迟到首次播放音效前再激活会话。提前激活会话会在应用切入前台时触发焦点抢占,导致背景音乐中断。优化后的完整配置代码
AudioSession.instance.then((session) async { await session.configure(AudioSessionConfiguration( // iOS配置 avAudioSessionCategory: AVAudioSessionCategory.ambient, avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.mixWithOthers, avAudioSessionMode: AVAudioSessionMode.defaultMode, avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy, avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none, // Android配置 androidAudioAttributes: const AndroidAudioAttributes( contentType: AndroidAudioContentType.sonification, flags: AndroidAudioFlags.none, usage: AndroidAudioUsage.game, ), androidAudioFocusGainType: AndroidAudioFocusGainType.gainTransientMayDuck, // 修改焦点类型 androidWillPauseWhenDucked: false, )); // 移除提前激活的代码,改为播放前激活 // await session.setActive(true); // 初始化音频播放器... });
播放音效时的补充处理
在首次播放计时器音效的方法中,添加会话激活逻辑:
Future<void> playTimerSound() async { final session = await AudioSession.instance; // 首次播放前激活音频会话 await session.setActive(true); // 执行音效播放逻辑 // audioPlayer.play(...); }
额外注意事项
- 确保音效的播放参数(如音量、循环模式)不会触发系统的焦点抢占逻辑。
- Android端若仍有问题,可尝试将
androidAudioAttributes的usage改为AndroidAudioUsage.notificationEvent,更贴合提示类音效的系统定义。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

