在Android(蓝牙低功耗)中启用蓝牙特性通知不起作用

sre*_*mar 3 android bluetooth bluetooth-lowenergy gatt

如果我们在一个字符上调用setCharacteristicNotification,而不是在值Change上给出远程通知?如何在蓝牙LE中的中央设备上启用远程通知?

sre*_*mar 12

要在Android上启用远程通知,

setCharacteristicNotification(特性,启用)是不够的.

需要为特征写出描述符.外围设备必须在创建特征时启用特征通知.

一旦通知被启用,这将有手柄的描述符0x2902.所以我们需要将BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE写入描述符.首先将0x2902转换为128位UUID,它将如此00002902-0000-1000-8000-00805f9b34fb(基本蓝牙UUID为0000xxxx-0000-1000-8000-00805f9b34fb).

代码如下

 protected static final UUID CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");


 * Enable Notification for characteristic
 *
 * @param bluetoothGatt
 * @param characteristic
 * @param enable
 * @return
 */
public boolean setCharacteristicNotification(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic characteristic,boolean enable) {
    Logger.d("setCharacteristicNotification");
    bluetoothGatt.setCharacteristicNotification(characteristic, enable);
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
    descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[]{0x00, 0x00});
    return bluetoothGatt.writeDescriptor(descriptor); //descriptor write operation successfully started?

}
Run Code Online (Sandbox Code Playgroud)

  • 如果characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID)返回null怎么办? (2认同)
  • 您的答案部分错误:0x2902 不可用,它始终存在,与启用与否无关。它的值表示是否启用了指示、通知或无。0x2902 是强制性的,应该始终存在。但是,某些特性可能不符合规格并跳过它,尤其是当它们没有指示/通知属性时 (2认同)

Don*_*oni 5

当调用descrpitor.setValue时,我也会收到空值,所以我只是在发现服务时将其打开,最后它工作得很好:

要通知主设备某些特性发生变化,请在外围设备上调用此函数:

private BluetoothGattServer server;
//init....

//on BluetoothGattServerCallback...

//call this after change the characteristic
server.notifyCharacteristicChanged(device, characteristic, false);
Run Code Online (Sandbox Code Playgroud)

在您的主设备中:发现服务后启用 setCharacteristicNotification:

@Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        services = mGatt.getServices();
        for(BluetoothGattService service : services){
            if( service.getUuid().equals(SERVICE_UUID)) {
                characteristicData = service.getCharacteristic(CHAR_UUID);
                for (BluetoothGattDescriptor descriptor : characteristicData.getDescriptors()) {
                    descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                    mGatt.writeDescriptor(descriptor);
                }
                gatt.setCharacteristicNotification(characteristicData, true);
            }
        }
        if (dialog.isShowing()){
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    dialog.hide();
                }
            });
        }
   }
Run Code Online (Sandbox Code Playgroud)

现在您可以检查您的特征值是否发生变化,例如 onCharacteristicRead 函数:

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.i("onCharacteristicRead", characteristic.toString());
        byte[] value=characteristic.getValue();
        String v = new String(value);
        Log.i("onCharacteristicRead", "Value: " + v);
}
Run Code Online (Sandbox Code Playgroud)