![](/img/trans.png)
[英]Flutter_blue and Adafruit Bluefruit BLE characteristic error: could not locate CCCD descriptor for characteristic
[英]flutter_blue: set_notification and read_characteristic errors on Android, BLE device disconnects on first connection attempt
我已经与 flutter 合作了几个星期,并且正在尝试构建一个应用程序来通过 BLE 与移动电源进行通信。 在其当前的 state 中,它在 iOS 上正常工作。 在 android 上,部分由于 BLE 设备的行为,我在连接/发现阶段抛出了异常。
void connect(String deviceId) async {
var dev = devices[deviceId];
if (connectedDevices[deviceId] != null) return;
await dev.device.connect(autoConnect: false);
dev.connection = dev.device.state.listen((state) async {
dev.deviceState = state;
notifyListeners();
if (state == BluetoothDeviceState.disconnected) {
connectedDevices[dev.id] = null;
await dev.dispose();
notifyListeners();
}
if (state == BluetoothDeviceState.connected) {
dev.services = await dev.device.discoverServices();
for (BluetoothService service in dev.services) {
// set services based on uuid
}
for (BluetoothCharacteristic characteristic
in dev.deviceInfoService.characteristics) {
// set characteristics from services
}
for (BluetoothCharacteristic characteristic
in dev.notificationService.characteristics) {
switch (characteristic.uuid.toString()) {
case notificationServiceCharacteristic:
dev.notificationServiceCharacteristic = characteristic;
if (!dev.notificationServiceCharacteristic.isNotifying) {
await dev.notificationServiceCharacteristic
.setNotifyValue(true);
dev.valueChangedSubscription = dev
.notificationServiceCharacteristic.value
.listen((value) {
_onValuesChanged(dev, value);
notifyListeners();
});
connectedDevices[dev.id] = dev;
}
break;
case writeCharacteristic:
dev.writeCharacteristic = characteristic;
break;
default:
break;
}
}
notifyListeners(); //using scopedModel for handling state
await readServiceCharacteristics(dev);
}
});
}
程序连接到设备。 连接后(状态 == BluetoothDeviceState.connected),发现服务和特征。 找到通知服务后,通过回调打开通知以处理数据。 完成此操作后,从只读特征中读取。
在 iOS 设备上,没有明显的错误。 程序正常运行; 尽管是由 BLE 设备引起的初始断开连接。 尝试重新连接成功,没有失败。
在 Android 上:抛出异常: /flutter ( 1557): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(set_notification_error, error when writing the descriptor, null)
负责线路:
await dev.notificationServiceCharacteristic
.setNotifyValue(true);
在我的研究中,我似乎已经找到了该错误的原因之一。 无论出于何种原因,BLE 设备都不会在第一次连接尝试时完成连接过程。 典型的连接工作如下:
首先,我从forEach
切换到for(BluetoothService service in dev.services)
“for-in” 样式,因为这样可以确保迭代等待回调/返回。
在调试中,我可以使用断点来确保程序不会抛出异常。 通过在等待行放置一个断点并等待一两秒钟,它可以正常工作。 在没有设置断点的情况下运行代码每次都会抛出错误,不会失败。
我用 RaisedButtons 构建了一个简单的 PoC 来调用初始化、扫描、连接和断开功能。 错误仍然存在
很明显,在设备的 state 的 StreamListener 中,它来自
虽然我知道这个问题部分是由 BLE 设备本身引起的,但我想知道是否有任何方法可以解决这个问题或解决它。 我正在考虑的一个想法是终止异步调用并设置某种标志的方法,以便在随后的调用中,程序知道清理和/或延迟以确保它可以正常工作。
我看过的一些 github 问题似乎遇到了类似的问题 - 解决方案通常是强制延迟或(在完美的世界中)没有最初断开连接的设备。 我将链接一些上下文:
特征是在设备重新连接时发送重复通知 #525 (不完全相同,但重复触发让我认为它并不太遥远)
无论哪种方式,感谢您的阅读,我希望尽快摆脱我身边的这根刺!
我不想冒犯你,但你的代码很难阅读。 首先,我建议您应该使用一些约定。 像 Future 一样,if 后面的花括号将这个巨大的方法分解成更小的方法。 我以前见过这个错误。 在这里,我建议一些解决方案。
所以基本上尽量使用特性,尽量避免并行请求。 希望对您有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.