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

Android Oreo系统蓝牙耳机录音异常问题求助

解决Android Oreo及以上版本蓝牙SCO录音异常问题

看起来你碰到了Android版本升级后蓝牙SCO录音的兼容性坑——Android 8.0(API 26)开始,系统对音频路由和录音源的管理做了大幅调整,之前KitKat到Nougat的适配逻辑在新系统上就失效了。我来给你拆解下问题和对应的解决方案:

1. 替换录音源为VOICE_COMMUNICATION

你之前用的MediaRecorder.AudioSource.MIC是通用麦克风源,在Oreo之后,蓝牙SCO连接建立后系统不会自动把这个源路由到蓝牙设备。换成VOICE_COMMUNICATION就不一样了,这个源是专门为语音通话/通信场景设计的,系统会自动优先将录音输入切换到蓝牙SCO设备。

修改后的AudioRecord配置代码:

final int RECORDER_SAMPLERATE = 8000;
final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
// 替换为专门的通信录音源
recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize);

2. 明确设置音频模式,强制路由到蓝牙SCO

在SCO连接成功后,除了调用setBluetoothScoOn(true),还需要把音频模式设置为MODE_IN_COMMUNICATION,这个模式会告诉系统当前是语音通信场景,必须优先使用蓝牙SCO设备的音频输入输出。

调整你的广播接收器逻辑:

if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
    am.setMode(AudioManager.MODE_IN_COMMUNICATION); // 新增这行,强制通信模式
    am.setBluetoothScoOn(true);
    unregisterReceiver(this);
    startRecord();
}

另外,建议在调用startBluetoothSco()之前就先设置好音频模式,避免路由冲突:

am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.setMode(AudioManager.MODE_IN_COMMUNICATION); // 提前设置模式
registerReceiver(...);
am.startBluetoothSco();

3. 适配Android Oreo的前台服务和权限要求

Android 8.0开始,前台服务必须显示通知,而且录音权限属于危险权限需要动态申请,蓝牙相关权限也得确保到位:

  • 动态申请录音权限:在启动录音前检查并申请RECORD_AUDIO权限
private static final int REQUEST_RECORD_PERMISSION = 101;

// 权限检查逻辑
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_RECORD_PERMISSION);
}
  • 前台服务通知:Android 8.0+要求前台服务必须绑定通知,否则会被系统杀死,在startRecord()里添加这段代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // 创建通知渠道
    NotificationChannel channel = new NotificationChannel("BT_RECORD_CHANNEL", "蓝牙录音服务", NotificationManager.IMPORTANCE_LOW);
    NotificationManager notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);
    
    // 创建前台通知
    Notification notification = new NotificationCompat.Builder(this, "BT_RECORD_CHANNEL")
            .setContentTitle("蓝牙录音中")
            .setSmallIcon(R.drawable.ic_notification) // 替换成你自己的图标
            .build();
    startForeground(1, notification);
}

4. Pixel设备的特殊适配:延迟启动录音

Pixel系列设备对音频路由的管控更严格,SCO连接成功的广播回调可能比系统实际完成路由切换要早,这时候启动录音会失败。可以加个1秒左右的延迟,等系统完成路由切换后再启动录音:

if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
    am.setMode(AudioManager.MODE_IN_COMMUNICATION);
    am.setBluetoothScoOn(true);
    unregisterReceiver(this);
    // 延迟1秒启动录音,给系统足够时间完成路由切换
    new Handler(Looper.getMainLooper()).postDelayed(() -> {
        startRecord();
    }, 1000);
}

另外,确认你的蓝牙耳机支持SCO协议(大部分通话耳机都支持,音乐耳机可能需要手动切换到通话模式)。

按上面的步骤调整后,应该就能解决华为荣耀8录音源错误和Pixel 2无法录音的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:44:15