Android BLE中心设备的onCharacteristicChanged()方法没有回调

描述:当设备为 Indication 模式时,设备的值有变化时会主动返回给App,App在 onCharacteristicChanged() 方法中能收到返回的值。

Indication: 从机会先向主机发送一条通知,主机接收到通知后去读取从机数据
Notification:从机直接发送给主机数据

问题:在App中通过如下代码注册监听,注册成功后就能接收到设备主动反馈的值了。然而以下代码执行后依旧收不到反馈。但是对设备的读写都是可行的,并且iOS端可以接收到通知。

bluetoothGatt.setCharacteristicNotification(characteristic, true)

解决: 当上面的方法执行返回true后,还要执行如下的代码才能注册成功。

for(BluetoothGattDescriptor dp: characteristic.getDescriptors()){
    if (dp != null) {
        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
            dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        } else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
            dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
        }
        gatt.writeDescriptor(dp);
    }
}

完整的代码如下:

public boolean enableNotification(BluetoothGatt gatt, UUID serviceUUID, UUID characteristicUUID) {
    boolean success = false;
    BluetoothGattService service = gatt.getService(serviceUUID);
    if (service != null) {
        BluetoothGattCharacteristic characteristic = findNotifyCharacteristic(service, characteristicUUID);
        if (characteristic != null) {
            success = gatt.setCharacteristicNotification(characteristic, true);
            if (success) {
                // 来源:http://stackoverflow.com/questions/38045294/oncharacteristicchanged-not-called-with-ble
                for(BluetoothGattDescriptor dp: characteristic.getDescriptors()){
                    if (dp != null) {
                        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                            dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                        } else if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0) {
                            dp.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                        }
                        gatt.writeDescriptor(dp);
                    }
                }
            }
        }
    }
    return success;
}

private BluetoothGattCharacteristic findNotifyCharacteristic(BluetoothGattService service, UUID characteristicUUID) {
    BluetoothGattCharacteristic characteristic = null;
    List characteristics = service.getCharacteristics();
    for (BluetoothGattCharacteristic c : characteristics) {
        if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0
                && characteristicUUID.equals(c.getUuid())) {
            characteristic = c;
            break;
        }
    }
    if (characteristic != null)
        return characteristic;
    for (BluetoothGattCharacteristic c : characteristics) {
        if ((c.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0
                && characteristicUUID.equals(c.getUuid())) {
            characteristic = c;
            break;
        }
    }
    return characteristic;
}

你可能感兴趣的:(Android)