Flutter中使用Flutter Reactive Ble接收蓝牙字符串遇连接断开问题
Flutter Reactive Ble 连接后读取特征导致设备断开的问题解决
问题根源
你的代码存在几个关键问题,导致设备连接后立即断开:
- 特征使用错误:NUS服务中,
bleNusCharRXUUID是设备接收数据的特征(用于APP向设备发送数据),通常不支持读操作;你需要接收设备发送的字符串,应该监听bleNusCharTXUUID(设备主动推送数据的特征)。 - 无差别触发读操作:在
connectToDevice的状态监听回调中,每次连接状态变化都会执行readCharacteristic,包括连接未就绪的状态,这会触发设备的错误处理逻辑导致断开。 - 重复创建实例:每次调用
foo都新建FlutterReactiveBle实例,会导致BLE连接管理混乱。 - 异步回调处理不当:
listen的异步回调未被正确处理,可能引发未捕获异常影响连接稳定性。
修正后的代码
// 复用类级别的FlutterReactiveBle实例,避免重复创建 final FlutterReactiveBle _flutterReactiveBle = FlutterReactiveBle(); // 预解析UUID常量,提升性能并避免重复代码 final Uuid _nusServiceUuid = Uuid.parse('6e400001-b5a3-f393-e0a9-e50e24dcca9e'); final Uuid _nusCharRxUuid = Uuid.parse('6e400002-b5a3-f393-e0a9-e50e24dcca9e'); final Uuid _nusCharTxUuid = Uuid.parse('6e400003-b5a3-f393-e0a9-e50e24dcca9e'); Future<void> connectAndListenToDevice(String deviceId) async { _flutterReactiveBle.connectToDevice( id: deviceId, servicesWithCharacteristicsToDiscover: {_nusServiceUuid: [_nusCharRxUuid, _nusCharTxUuid]}, connectionTimeout: const Duration(seconds: 2), ).listen((connectionState) { // 仅在连接成功状态下执行特征监听 if (connectionState.connectionState == DeviceConnectionState.connected) { final txCharacteristic = QualifiedCharacteristic( serviceId: _nusServiceUuid, characteristicId: _nusCharTxUuid, deviceId: deviceId, ); // 订阅TX特征的通知,接收设备主动发送的数据 _flutterReactiveBle.subscribeToCharacteristic(txCharacteristic).listen((dataBytes) { // 将字节数组转换为字符串 final receivedString = String.fromCharCodes(dataBytes); print('收到设备消息:$receivedString'); }, onError: (error) { print('特征监听出错:$error'); }); } }, onError: (error) { print('设备连接失败:$error'); }); }
关键说明
- 正确使用NUS特征:
TX特征(6e400003...):设备向APP推送数据的通道,必须通过subscribeToCharacteristic订阅通知来接收持续的数据流。RX特征(6e400002...):APP向设备发送数据的通道,使用writeCharacteristic方法写入数据。
- 状态判断:仅当连接状态变为
DeviceConnectionState.connected时,再执行特征相关操作,确保设备就绪。 - 复用实例:全局/类级别复用
FlutterReactiveBle实例,避免BLE资源冲突。 - 订阅而非读取:设备主动发送的数据是通过BLE通知机制传递的,主动读取
readCharacteristic只能获取一次特征值,无法接收实时推送的数据流。
内容的提问来源于stack exchange,提问作者LucasMnzb
相关产品推荐
相关产品推荐

