Flutter Blue Plus设置通知触发PlatformException问题求助
Flutter Blue Plus 设置蓝牙通知触发
gatt.writeDescriptor() returned false 异常的解决方法 问题描述
成功连接蓝牙设备并找到指定服务(0000fff0-0000-1000-8000-00805f9b34fb)、特征(0000fff4-0000-1000-8000-00805f9b34fb)后,调用 await characteristic.setNotifyValue(true) 抛出异常:
PlatformException (PlatformException(setNotification, gatt.writeDescriptor() returned false, null, null))
原实现代码:
void connectToDevice() async { deviceConnectionSubscription = foundDevice?.state.listen((state) { if (state == BluetoothConnectionState.connected) { setState(() { isConnected = true; }); } else if (state == BluetoothConnectionState.disconnected) { setState(() { isConnected = false; }); } }); var lock = new Lock(); await foundDevice?.connect(autoConnect: true); List<BluetoothService>? services = await foundDevice?.discoverServices(); if (services != null) { chr = services; print(services); if (services.isNotEmpty) { for (BluetoothService service in services) { if (service.uuid.toString() == "0000fff0-0000-1000-8000-00805f9b34fb") { List<BluetoothCharacteristic> characteristics = service.characteristics; for (BluetoothCharacteristic characteristic in characteristics) { if (characteristic.uuid.toString() == "0000fff4-0000-1000-8000-00805f9b34fb") { print("Characteristic found"); await characteristic.setNotifyValue(true); characteristic.value.listen((value) { hexNumbere(value); }); } } } } } } }
解决步骤
1. 验证特征是否支持通知权限
先确认目标特征具备通知属性,找到特征时打印其权限信息:
print("Characteristic properties: ${characteristic.properties}");
若输出不包含 BluetoothCharacteristicProperty.notify,说明该特征不支持通知,需更换特征或检查设备端蓝牙配置。
2. 延迟操作确保连接稳定
原代码在connect后立即调用discoverServices,但蓝牙连接状态切换是异步的,可能连接未完全就绪。建议将服务发现、通知设置逻辑移到connected状态回调中:
void connectToDevice() async { deviceConnectionSubscription = foundDevice?.state.listen((state) async { if (state == BluetoothConnectionState.connected) { setState(() { isConnected = true; }); // 连接稳定后再执行服务发现和通知设置 await discoverServicesAndSetNotification(); } else if (state == BluetoothConnectionState.disconnected) { setState(() { isConnected = false; }); } }); await foundDevice?.connect(autoConnect: true); } Future<void> discoverServicesAndSetNotification() async { List<BluetoothService>? services = await foundDevice?.discoverServices(); if (services != null && services.isNotEmpty) { for (BluetoothService service in services) { if (service.uuid.toString() == "0000fff0-0000-1000-8000-00805f9b34fb") { for (BluetoothCharacteristic characteristic in service.characteristics) { if (characteristic.uuid.toString() == "0000fff4-0000-1000-8000-00805f9b34fb") { print("Characteristic found"); // 检查通知权限 if (characteristic.properties.contains(BluetoothCharacteristicProperty.notify)) { try { bool success = await characteristic.setNotifyValue(true); print("Set notify result: $success"); if (success) { characteristic.value.listen((value) { hexNumbere(value); }); } } catch (e) { print("Set notify error: $e"); // 手动操作CCC描述符启用通知 var cccDescriptor = characteristic.descriptors.firstWhere( (d) => d.uuid.toString() == "00002902-0000-1000-8000-00805f9b34fb", orElse: () => throw Exception("CCC descriptor not found") ); await cccDescriptor.write([0x01, 0x00]); } } else { print("Characteristic does not support notify"); } } } } } } }
3. 手动写入CCC描述符
若自动调用setNotifyValue失败,可手动找到CCC描述符(UUID: 00002902-0000-1000-8000-00805f9b34fb),写入指令[0x01, 0x00]启用通知,这是GATT协议的标准操作。
4. 检查设备端配置与连接参数
- 确认蓝牙设备的目标特征已开启通知权限,且CCC描述符可写;
- 若设备对MTU有要求,可在
discoverServices前请求更大的MTU:await foundDevice?.requestMtu(512);
内容的提问来源于stack exchange,提问作者NDN
相关产品推荐
相关产品推荐

