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

Flutter应用在后台时如何播放提示音?

Flutter应用后台/最小化状态下播放提示音解决方案

问题描述

我正在给Flutter应用集成计时器功能,要求计时器结束时播放提示音。前台状态下功能正常,但应用后台或最小化时,即使代码逻辑正常执行,也没有声音输出。

负责播放声音的代码:

_beep({
  required bool isDrivenByTimerController,
  required bool isLast,
}) {
  // 通过riverpod获取audio服务
  final audio = ref.read(audioTimerProvider);

  // 播放提示音
  audio.item1.seek(Duration.zero);
  audio.item1.play();
}

应用生命周期处理代码(后台触发无声音):

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  if (state == AppLifecycleState.resumed) {
    _timer?.cancel();
  }

  // 应用进入后台时,根据剩余时间调度计时器并播放提示音
  if (state == AppLifecycleState.paused) {
    // ... 计算timeLeft值 ...

    Timer(timeLeft, () {
      // 此处无声音输出
      _beep(
        isDrivenByTimerController: false,
        isLast: true,
      );
    });
  }
}

已尝试的无效方案

  • 使用just_audio_background插件:仅支持前台启动的长音频播放,无法在后台触发新的音频播放
  • Xcode中启用“Audio, Airplay, and Picture in Picture”权限:无效果
  • 在独立隔离区运行音频播放:音频需主线程执行,失败
  • 使用workmanager包:无法保证计时器的精准调度
  • 使用flutter_local_notifications包:iOS要求必须显示通知横幅,且用户可禁用通知,不符合需求

可行实现方案(针对iOS)

参考示例应用的实现逻辑,核心是利用iOS的音频会话配置+后台任务调度来实现精准触发:

  1. 配置iOS音频会话
    在iOS原生AppDelegate.swift中设置音频会话类别为播放模式,允许后台活跃:

    import AVFoundation
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        do {
            // 设置音频会话为播放模式,允许混合其他音频、AirPlay
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay])
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print("音频会话配置失败: \(error)")
        }
        return true
    }
    
  2. 用后台任务替代Timer
    iOS的Timer在后台会被暂停,改用BGTaskScheduler调度后台任务,确保到点时应用短暂唤醒执行播放:

    • 在Xcode的Info.plist中添加BGTaskSchedulerPermittedIdentifiers,注册自定义任务ID(比如com.your.app.timerbeep)
    • 原生端实现任务的调度和处理逻辑,任务触发时通过MethodChannel调用Flutter的_beep方法
    • Flutter端在应用进入后台时,计算剩余时间并通知原生端调度对应时长的后台任务
  3. 预加载音频资源
    在应用前台初始化阶段就加载好提示音资源,避免后台时因资源加载失败无法播放:

    @override
    void initState() {
      super.initState();
      final audio = ref.read(audioTimerProvider);
      // 提前加载音频文件(替换为你的资源路径)
      audio.item1.setAsset('assets/sounds/beep.mp3');
    }
    

注意事项

  • iOS后台任务的执行时间有严格限制(通常几秒),播放短提示音完全符合要求
  • 必须正确配置音频会话,否则即使唤醒应用也无法输出声音
  • 后台任务不要执行多余操作,避免被App Store审核拒绝

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:57:08