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

使用expo-av的React Native应用Android12接电话后录音无法恢复

修复Android 12下Expo 45录音应用通话后无声问题

问题根源

Android 12对音频焦点管理和后台音频处理机制做了严格限制,Expo 45内置的expo-av版本未完全适配该变化,导致通话结束后原录音实例无法重新获取音频焦点恢复采集,进而出现持续无声的情况。旧版Android系统的音频焦点逻辑更宽松,所以挂断后能自动恢复。

具体修复方案

1. 监听音频焦点变化,主动暂停/重启录音

利用expo-av的音频焦点监听,在通话触发焦点丢失时暂停录音,焦点恢复时重启录音实例(而非单纯恢复原实例),这是适配Android 12的核心操作:

import { Audio } from 'expo-av';

let currentRecording = null;
let wasRecordingBeforeFocusLoss = false;

// 初始化音频焦点监听
const setupAudioFocusHandler = () => {
  Audio.addAudioFocusListener((focusEvent) => {
    switch(focusEvent.type) {
      // 音频焦点恢复(通话结束)
      case Audio.AudioFocusLossType.Gain:
        if (wasRecordingBeforeFocusLoss) {
          restartRecording();
          wasRecordingBeforeFocusLoss = false;
        }
        break;
      // 临时丢失焦点(通话开始)
      case Audio.AudioFocusLossType.LossTransient:
      case Audio.AudioFocusLossType.Loss:
        if (currentRecording) {
          pauseRecording();
          wasRecordingBeforeFocusLoss = true;
        }
        break;
    }
  });
};

// 暂停当前录音
const pauseRecording = async () => {
  try {
    await currentRecording.pauseAsync();
  } catch (err) {
    console.error('暂停录音失败:', err);
    // 暂停失败则直接停止实例
    await currentRecording.stopAndUnloadAsync();
    currentRecording = null;
  }
};

// 重启录音(创建新实例)
const restartRecording = async () => {
  // 清理旧实例
  if (currentRecording) {
    await currentRecording.stopAndUnloadAsync();
    currentRecording = null;
  }
  // 创建新录制实例并启动
  const newRecording = new Audio.Recording();
  try {
    await newRecording.prepareToRecordAsync(Audio.RecordingOptionsPresets.HIGH_QUALITY);
    await newRecording.startAsync();
    currentRecording = newRecording;
  } catch (err) {
    console.error('重启录音失败:', err);
  }
};

2. 补充Android 12所需权限

在app.json的Android配置中添加必要权限,确保应用能在后台处理录音和音频焦点:

{
  "expo": {
    "android": {
      "permissions": [
        "RECORD_AUDIO",
        "FOREGROUND_SERVICE"
      ]
    }
  }
}
  • FOREGROUND_SERVICE:Android 12要求后台录音的应用必须以前台服务运行,避免被系统回收。
  • RECORD_AUDIO:确保麦克风权限正常授予(需在运行时动态请求)。

3. 升级expo-av到Expo 45兼容的最新补丁版

Expo 45对应的expo-av版本为11.x,部分早期版本存在Android 12适配bug,可升级到该分支的最新版本(如11.2.3),执行命令:

expo install expo-av@11.2.3

查看补丁日志,确认是否包含Android 12音频焦点修复。

4. 优化录制配置

在prepareToRecordAsync中明确指定Android相关参数,确保录音实例优先级正确:

const recordingOptions = {
  ...Audio.RecordingOptionsPresets.HIGH_QUALITY,
  android: {
    audioSource: Audio.RECORDING_OPTION_ANDROID_AUDIO_SOURCE_MIC,
    audioEncoder: Audio.RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC,
    outputFormat: Audio.RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4,
  },
};
await newRecording.prepareToRecordAsync(recordingOptions);

关键注意事项

  • Android 12下,原录音实例在焦点丢失后大概率无法复用,必须创建新实例才能恢复正常录音;
  • 若需要拼接通话前后的录音片段,可在暂停时保存旧录音文件路径,结束后通过音频处理工具合并(如expo-av的音频拼接API)。

内容的提问来源于stack exchange,提问作者Grzegorz Brzęczyszczykiewicz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:25:23