Tushar H
Tushar H

Reputation: 795

Android BLE onCharacteristicChanged not triggering

I have an medical device(named as SnoreCoach), I have created an android app and did Bluetooth Low Energy connectivity with this device. Everything (connecting to device, writing data to characteristics etc.) is working fine except OnCharacteristicChanged is not getting triggered.

Following is my BluetoothGattCallback:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            broadcastUpdate(ACTION_GATT_CONNECTED);
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            broadcastUpdate(ACTION_GATT_DISCONNECTED);
        }

    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "onServicesDiscovered - success");
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        }
    }

 @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicRead(gatt, characteristic, status);
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "onCharacteristicRead - success");
            broadcastUpdate(ACTION_DATA_AVAILABLE);
        }
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicWrite(gatt, characteristic, status);
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "onCharacteristicWrite - success");
            if (writeType.equals("unPair")) {
                mBluetoothGatt.close();
                mBluetoothGatt = null;
                currentlyConnectedPeripheral = null;
            }
        }
    }

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

    @Override
    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
        super.onReliableWriteCompleted(gatt, status);
        Log.d(TAG, "onReliableWriteCompleted");
    }

    @Override
    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
        super.onReadRemoteRssi(gatt, rssi, status);
        Log.d(TAG, "onReadRemoteRssi");
    }

    @Override
    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
        super.onMtuChanged(gatt, mtu, status);
        Log.d(TAG, "onMtuChanged");
    }
};

Following is the "broadcastUpdate" function called from above BluetoothGattCallback:

private void broadcastUpdate(final String action) {
    final Intent intent = new Intent(action);
    sendBroadcast(intent);
}

In my calling activity (SettingsActivity) I have following broadcast receiver:

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        switch (action) {
            case BLEService.ACTION_GATT_CONNECTED:
                displayToast("Connected");
                Log.d(TAG, "Connected");
                mBleService.discoverServices();
                break;
            case BLEService.ACTION_GATT_DISCONNECTED:
                displayToast("Disconnected");
                break;
            case BLEService.ACTION_GATT_SERVICES_DISCOVERED:
                Log.d(TAG, "Services Discovered");
                displayToast("Services Discovered");
                mBleService.enableNotification();
                break;
            case BLEService.ACTION_DATA_AVAILABLE:
                displayToast("Data Received");
                break;
        }
    }
};

And below is my "enableNotification" functions:

 public void enableNotification() {
    BluetoothGattService snorecoachService = mBluetoothGatt.getService(SNORECOACH_SERVICE_UUID);
    if (snorecoachService == null) {
        Log.d(TAG, "snorecoach Service not found!");
        return;
    }

    BluetoothGattCharacteristic bodyMovementChar = snorecoachService.getCharacteristic(BODY_MOVEMENT_UUID);
    if (bodyMovementChar == null) {
        Log.d(TAG, "charateristic not found!");
        return;
    }

    mBluetoothGatt.setCharacteristicNotification(bodyMovementChar, true);

    BluetoothGattDescriptor desc = bodyMovementChar.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
    desc.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
    mBluetoothGatt.writeDescriptor(desc);
}

Following is the flow :

1) On connection, I send an broadcast as "connected" to mGattUpdateReceive, here I then start service discovery.

2) OnServiceDiscovery, I send an broadcast as "Services Discovered" to mGattUpdateReceive, here I call "enable notofication" function to set "setCharacteristicNotification", which writes the required descriptor too.

I have tried all possible options I found from other stackOverflow questions, But I don't know what I am doing wrong that the onCharacteristic event is not getting triggered.

I have spent more than 2 days for solving this but no luck, so any help would be greatly appreciated.

Upvotes: 0

Views: 1520

Answers (1)

Emil
Emil

Reputation: 18442

If it is notifications you want rather than indications, try to change

desc.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);

to

desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

Upvotes: 1

Related Questions