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

Flutter Android端视频录制切换蓝牙麦克风的问题及排查

解决Flutter视频录制切换蓝牙麦克风(S280)的问题

核心问题分析

从日志可见,你的S280蓝牙麦克风设备类为1028(十六进制0x404),对应BluetoothClass.Device.AUDIO_VIDEO_HEADSET,但你代码中仅判断AUDIO_VIDEO_MICROPHONE,导致设备无法被识别。此外,蓝牙SCO连接需要等待确认,不能直接启动录制。

解决方案步骤

1. 修复蓝牙设备识别逻辑

替换原有设备判断逻辑,优先通过设备名称匹配(针对特定设备更可靠,避免类标记不标准问题),也可兼容HEADSET类:

// 方式1:直接匹配S280设备名称
if (device.name.equals("S280", ignoreCase = true)) {
    // 执行蓝牙连接逻辑
}

// 方式2:兼容麦克风和耳机类设备
val deviceClass = device.bluetoothClass.deviceClass
if (deviceClass == BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE 
    || deviceClass == BluetoothClass.Device.AUDIO_VIDEO_HEADSET) {
    // 执行蓝牙连接逻辑
}

2. 优化蓝牙SCO连接流程

添加SCO连接状态监听,确保连接成功后再通知Flutter启动录制:

@SuppressLint("MissingPermission")
private fun switchToBluetoothMicrophone(result: MethodChannel.Result) {
    val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
    // 省略原有蓝牙支持、启用、配对设备检查逻辑...

    var foundBluetoothMic = false
    for (device in pairedDevices) {
        Log.d(TAG, "Device Name: ${device.name}, Device Address: ${device.address}, Class: ${device.bluetoothClass.deviceClass}")

        if (device.name.equals("S280", ignoreCase = true)) {
            Log.d(TAG, "Found Bluetooth microphone: ${device.name}")
            val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager

            // 注册SCO连接状态监听器
            val scoListener = object : AudioManager.OnBluetoothScoStateChangedListener {
                override fun onBluetoothScoStateChanged(state: Int, previousState: Int) {
                    if (state == AudioManager.SCO_CONNECTED) {
                        Log.d(TAG, "Bluetooth SCO connected successfully")
                        audioManager.isMicrophoneMute = false
                        audioManager.isSpeakerphoneOn = false
                        result.success("Bluetooth microphone activated and connected.")
                        audioManager.unregisterBluetoothScoStateListener(this)
                    } else if (state == AudioManager.SCO_DISCONNECTED) {
                        Log.e(TAG, "Bluetooth SCO disconnected")
                        result.error("SCO_DISCONNECTED", "Failed to connect to Bluetooth microphone.", null)
                        audioManager.unregisterBluetoothScoStateListener(this)
                    }
                }
            }

            audioManager.registerBluetoothScoStateListener(scoListener)
            audioManager.mode = AudioManager.MODE_IN_CALL
            audioManager.isBluetoothScoOn = true
            audioManager.startBluetoothSco()

            foundBluetoothMic = true
            break
        } else {
            Log.d(TAG, "Not target device: ${device.name}")
        }
    }

    if (!foundBluetoothMic) {
        Log.e(TAG, "No Bluetooth microphone found.")
        result.error("NO_BLUETOOTH_MIC", "No Bluetooth microphone found.", null)
    }
}

3. Flutter端调整:等待连接成功再启动录制

修改录制方法,确保收到蓝牙切换成功回调后再启动录制:

Future<void> startVideoRecording() async {
    if (!_isCameraInitialized || _isRecording) return;

    try {
      // 等待蓝牙切换成功
      final String result = await BluetoothAudioHelper.switchToBluetoothMicrophone();
      print(result);

      // 确认连接成功后启动录制
      await _cameraController.startVideoRecording();
      _isRecording = true;
      _mediaPath = null;
      _isCameraMode = false;
      startTimer();
      _setOrientationDuringRecording();
      notifyListeners();
    } on PlatformException catch (e) {
      print('Failed to switch microphone or start recording: ${e.message}');
    } catch (e) {
      print('Error starting video recording: $e');
    }
}

4. 补充必要权限

确保AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- Android 12+ 额外权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

关键说明

  • 部分蓝牙设备的BluetoothClass标记不标准,直接匹配设备名称或MAC地址是更可靠的方式。
  • 蓝牙SCO连接需要时间,必须监听连接状态,不能立即启动录制,否则音频源可能未切换成功。
  • 必须授予MODIFY_AUDIO_SETTINGS权限,否则无法切换音频输入源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:37:32