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
相关产品推荐
相关产品推荐

