为什么setCharacteristicNotification()实际上没有启用通知?

时间:2014-04-02 16:01:31

标签: android bluetooth bluetooth-lowenergy gatt

BluetoothLeGatt Android BLE示例包含以下代码:

public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
                                          boolean enabled) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

    // This is specific to Heart Rate Measurement.
    if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
                UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
    }
}

我的问题基本上是,为什么标记的代码特定于心率测量?似乎具有客户端特征配置描述符(CCCD)特征是控制特征通知的标准方法,那么为什么没有setCharacteristicNotification()负责写入它?既然它没有这样做,setCharacteristicNotification()实际上做了什么?

我对BLE很陌生,互联网上没有任何解释,不要以为你已经理解了这一切!所以不要以为我知道什么是CCCD或其他什么!找出CCCD甚至代表什么是很困难的!

编辑:另请参阅此答案,该答案支持我对CCCD的理解(并且让我继续想知道为什么你必须在Android中手动写入它们,当有一个看起来的功能时应该这样做对你而言):https://devzone.nordicsemi.com/index.php/what-does-cccd-mean

5 个答案:

答案 0 :(得分:8)

我觉得回答有点迟,但今天我有同样的疑问,我找到了一个明确的答案。 使用setCharacteristicNotification()启用通知localy(在Android设备上)并将CCC描述符设置为ENABLE_NOTIFICATION_VALUE,您可以在ble外设上启用通知。事实上,为了启用CCC通知,您必须使用setValue()writeDescriptor()这些方法,这些方法用于向远程设备写入特征(在本例中为特征描述符)。 我在http://processors.wiki.ti.com/index.php/SensorTag_User_Guide

上找到了这个

答案 1 :(得分:6)

以下是O'Reilly出版的“蓝牙低功耗入门”一书的摘录:

  

要在Android上启用通知,您通常必须在本地   启用您所特定特征的通知   感兴趣的。

     

完成后,您还必须在对等方上启用通知   通过写入设备的客户端特性配置来实现设备   描述符(CCCD)

我相信这会回答你的问题。

所以

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled); 

指的是第一部分

mBluetoothGatt.writeDescriptor(descriptor); 

指的是第二个。

答案 2 :(得分:4)

对于未来的人们来说,这是我能找到的最佳答案:

通过写入客户端特性配置描述符,您(客户端)告诉BLE服务器切换配置。 (这对我来说没有任何意义,但在英语中:)

这告诉BLE设备切换模式(配置)以主动收集和报告对此特征的更改,而不是更改并仅在请求时进行报告。

它的名字很差,但是在浏览文档时,它似乎也将用于客户端可能要求的其他可能的特征更改:因此名称混乱。

https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml

这引出了一个问题,如果我们只是通过修改描述符来复制我们的工作,为什么要调用BluetoothGatt.setCharacteristicNotification()?挖掘BluetoothGatt来源向我们显示,setCharacteristicNotification仅为接收通知准备本地服务,而不是启用持久更新。

答案 3 :(得分:0)

我知道它看起来很愚蠢,但设置CCCD值是告诉API是否打开通知或指示的唯一方法。

目前没有setCharacteristicIndication。要启用指示,您必须调用setCharacteristicNotification(令人困惑),然后将BluetoothGattDescriptor.ENABLE_INDICATION_VALUE写入CCCD,类似于您启用通知所做的操作。

答案 4 :(得分:0)

所有其他答案都没有真正回答问题。

我的猜测是 Android BLE 团队假设一个应用程序可能有多个 BluetoothGattCallback()

通过将通知启用(和禁用)分成两步,它会允许 BluetoothGattCallback 观察者监听 GATT 通知(仅调用 setCharacteristicNotification()) - 并且只留下一个 BluetoothGattCallback 实现对 GATT 服务器(即 BLE 外设)执行写入操作。