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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:04:52