Search code examples
androidbluetooth-lowenergygatt

setCharacteristicNotification doesn't trigger onCharacteristicChanged


I try to read peripheral's characteristic however onCharacteristicChanged is never called despite setting up setCharacteristicNotification.

Method which gets my characteristic:

private void getCharacteristic(List<BluetoothGattService> gattServices) {
    if (gattServices == null) return;

    for (BluetoothGattService gattService : gattServices) {
        if (gattService.getUuid().toString().equals("000018f0-0000-1000-8000-00805f9b34fb")) {
            for (BluetoothGattCharacteristic gattCharacteristic : gattService.getCharacteristics()) {
                if (gattCharacteristic.getUuid().toString().equals("00002af0-0000-1000-8000-00805f9b34fb")) {
                    mBluetoothLeService.setCharacteristicNotification(gattService.getCharacteristic(gattCharacteristic.getUuid()), true);
                }
            }
        }
    }
}

Setting up notifications:

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

onCharacteristicChanged method which is never triggered:

@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
        Log.d(TAG, "characteristic changed");
        broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}

The same code works fine with different peripherals.

I also downloaded nRF Connect app from Google Play store which displays characteristics and when i enabled notifications in nRF Connect, onCharacteristicChanged in my app started to get called (I could see "characteristic changed" in logcat).


Solution

  • I solved the problem. I had to writeDescriptor to my BluetoothGatt, so my setCharacteristicNotificiation looks like this:

    public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
                                                  boolean enabled) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
    
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
            UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBluetoothGatt.writeDescriptor(descriptor);
    }