如何实现Flutter应用后台持续麦克风录制功能?
Flutter后台持续音频录制实现方案
问题背景
基于Flutter开发音频录制应用,使用flutter_sound和path_provider实现基础录制逻辑,但应用进入后台几秒后麦克风停止采集,返回前台录制恢复正常。需实现后台持续录音,同时了解iOS和Android的权限配置与限制规避方案。
现有实现代码
import 'package:flutter/material.dart'; import 'package:flutter_sound/flutter_sound.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Audio Recorder', theme: ThemeData(primarySwatch: Colors.blue), home: AudioRecorderWidget(), ); } } class AudioRecorderWidget extends StatefulWidget { @override _AudioRecorderWidgetState createState() => _AudioRecorderWidgetState(); } class _AudioRecorderWidgetState extends State<AudioRecorderWidget> { final FlutterSoundRecorder _recorder = FlutterSoundRecorder(); final FlutterSoundPlayer _player = FlutterSoundPlayer(); bool isRecording = false; String? filePath; @override void initState() { super.initState(); initAudio(); } Future<void> initAudio() async { await _recorder.openRecorder(); await _player.openPlayer(); } Future<void> startRecording() async { try { Directory appDocDir = await getApplicationDocumentsDirectory(); filePath = '${appDocDir.path}/recorded_audio.aac'; await _recorder.startRecorder(toFile: filePath); setState(() { isRecording = true; }); } catch (e) { print("Error starting recording: $e"); } } Future<void> stopRecording() async { try { await _recorder.stopRecorder(); setState(() { isRecording = false; }); } catch (e) { print("Error stopping recording: $e"); } } Future<void> playRecording() async { if (filePath != null) { await _player.startPlayer(fromURI: filePath); } } @override void dispose() { _recorder.closeRecorder(); _player.closePlayer(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Audio Recorder')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: isRecording ? null : startRecording, child: Text('Start Recording'), ), ElevatedButton( onPressed: isRecording ? stopRecording : null, child: Text('Stop Recording'), ), ElevatedButton( onPressed: !isRecording && filePath != null ? playRecording : null, child: Text('Play Recording'), ), if (isRecording) Padding( padding: const EdgeInsets.all(8.0), child: CircularProgressIndicator(), ), ], ), ), ); } }
遇到的问题
应用进入后台后几秒内麦克风停止采集,返回前台后录制恢复正常。
已尝试方案
- 了解过画中画模式保持应用活跃,但希望探索其他方案;
- 查询Flutter官方文档未找到后台持续录音的直接实现方法。
解决方案
一、权限配置(iOS + Android)
Android 端
- 添加权限到
AndroidManifest.xml
在android/app/src/main/AndroidManifest.xml中添加以下权限:<!-- 基础录音权限 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- Android 10+ 后台录音权限 --> <uses-permission android:name="android.permission.RECORD_AUDIO_BACKGROUND" /> <!-- 申请忽略电池优化权限 --> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> - 声明前台服务类型
在<application>标签内添加服务声明,指定麦克风类型的前台服务:
Android 12+要求后台访问麦克风必须使用<service android:name="com.dooboolab.fluttersound.FlutterSoundRecorderService" android:foregroundServiceType="microphone" />microphone类型的前台服务,避免系统终止进程。 - 主动请求忽略电池优化
在代码中添加请求逻辑,避免系统因省电策略终止后台录制:
可在应用初始化或开始录制前调用该方法。import 'package:permission_handler/permission_handler.dart'; Future<void> requestBatteryOptimization() async { if (await Permission.ignoreBatteryOptimizations.isDenied) { await Permission.ignoreBatteryOptimizations.request(); } }
iOS 端
- 添加权限到
Info.plist
在ios/Runner/Info.plist中添加麦克风权限说明和后台音频模式:
开启<!-- 麦克风权限说明 --> <key>NSMicrophoneUsageDescription</key> <string>需要访问麦克风进行音频录制</string> <!-- 开启后台音频模式 --> <key>UIBackgroundModes</key> <array> <string>audio</string> </array>audio后台模式后,iOS允许应用在后台持续处理音频录制。 - 配置音频会话
初始化阶段配置正确的音频会话类别,确保后台录音权限生效:
在import 'package:audio_session/audio_session.dart'; Future<void> initAudioSession() async { final session = await AudioSession.instance; await session.configure(AudioSessionConfiguration( avAudioSessionCategory: AVAudioSessionCategory.playAndRecord, avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth | AVAudioSessionCategoryOptions.mixWithOthers, avAudioSessionMode: AVAudioSessionMode.spokenAudio, )); await session.setActive(true); }initAudio()方法中先调用该配置,再打开flutter_sound录制器。
二、Flutter Sound 配置优化
调用startRecorder时指定合适的音频源,并确保启用后台支持:
await _recorder.startRecorder( toFile: filePath, audioSource: AudioSource.microphone, codec: Codec.aacADTS, );
三、备选方案
如果flutter_sound后台支持不稳定,可使用audio_service包结合原生录制逻辑,将录制任务放在后台服务中执行,不受前台生命周期影响。
内容的提问来源于stack exchange,提问作者Ashish Tandon
相关产品推荐
相关产品推荐

