Android 11下MediaRecorder录制通话音频setAudioSource失败如何解决
问题原因
Android 11(API 30)对音频输入能力做了两项核心变更,直接导致你现有代码报错:
- 后台麦克风访问限制:Android 11 禁止应用在后台进程未启动前台服务的情况下访问麦克风,你如果在后台线程、广播接收器或未声明对应类型的前台服务中调用
setAudioSource,系统会直接拒绝音频源访问,抛出该异常 - 音频源权限收紧:
VOICE_COMMUNICATION作为面向VoIP通话场景的音频源,Android 11开始仅允许前台进程调用,如果是录制运营商蜂窝通话,原生系统已完全禁止第三方非拨号应用访问通话音频流,仅厂商定制系统可通过额外权限开放该能力 - 你当前配置的权限缺少Android 11及以上版本要求的前台录音相关权限,且存储权限配置不符合分区存储规则
适配方案
按以下步骤调整即可适配Android 11及以上系统:
1. 更新AndroidManifest.xml配置
<!-- 原有基础权限保留,调整存储权限适配分区存储 --> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:minSdkVersion="33" /> <!-- 新增Android 11及以上前台录音所需权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" android:minSdkVersion="33" /> <!-- 声明录音专用前台服务,指定服务类型 --> <service android:name=".AudioRecordService" android:foregroundServiceType="microphone" android:exported="false" />
2. 调整录音执行逻辑
所有录音初始化、启动逻辑必须放在声明了microphone类型的前台服务中执行,禁止在后台直接调用。
3. 优化录音初始化代码
// 执行录音前先校验运行时权限,确保RECORD_AUDIO已被用户授权 if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1001); return; } // 前台服务中执行录音初始化逻辑 MediaRecorder recorder = new MediaRecorder(); // 适配不同系统版本的音频源 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // Android 11及以上优先使用MIC,VoIP场景可保留VOICE_COMMUNICATION recorder.setAudioSource(MediaRecorder.AudioSource.MIC); } else { recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION); } recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 存储路径使用App专属目录,避免分区存储限制 File audioFile = new File(getExternalFilesDir(Environment.DIRECTORY_RECORDINGS), "record.amr"); recorder.setOutputFile(audioFile.getAbsolutePath()); recorder.prepare(); recorder.start();
额外说明
如果你的需求是录制运营商蜂窝通话,原生Android 11及以上系统默认禁止第三方应用实现该功能,仅系统默认拨号应用可使用。国内厂商定制系统可引导用户手动开启权限管理中的「通话录音」特殊权限,即可正常录制通话音频。
内容的提问来源于stack exchange,提问作者amir shahpoori
相关产品推荐
相关产品推荐

