3

I am trying to develop a BT application for connecting to a BLE device and read some data from it. For the device information part, I am looping through all the characteristics of the device, read the characteristic and collect returned data from the onCharacteristicRead method of BluetoothGattCallback.

The issue is that for the loop the onCharacteristicRead method is called only once. Please refer the code and the logcat below.

 @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            String value = characteristic.getStringValue(0);
            Log.e("TAG", "onCharacteristicRead: " + value + " UUID " + characteristic.getUuid().toString() );

        }

Characteristics are looped as

private void getDeviceInformation() {
    BluetoothGattService deviceInfoService = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE);
    BluetoothGattCharacteristic deviceSerialNumber, deviceHardwareRevision, deviceSoftwareRevision;


    for (BluetoothGattCharacteristic characteristic : bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE).getCharacteristics()) {
        bluetoothGatt.setCharacteristicNotification(characteristic, true);
        bluetoothGatt.readCharacteristic(characteristic);
    }
}

Logcat -

D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a25-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a27-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a28-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a23-0000-1000-8000-00805f9b34fb enable: true
D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a50-0000-1000-8000-00805f9b34fb enable: true
W/BluetoothGatt: onCharacteristicRead() - Device=F6:8B:C2:F3:EB:EE handle=14 Status=0
E/TAG: onCharacteristicRead: 86a691595263 UUID 00002a25-0000-1000-8000-00805f9b34fb
Kshitij
  • 392
  • 2
  • 13
  • it will not work in loop. try to read second characterstic after callback of first read. – D.J Nov 21 '17 at 09:20
  • I tried to define them separately. It doesn't work either. Though they were written in the same function. – Kshitij Nov 21 '17 at 10:04
  • Take a counter variable starting from 0 and read first characterstic. after call back of first characterstics read then increase counter to one and read second characterstic and so on. – D.J Nov 21 '17 at 10:09

1 Answers1

4

You should make all your operation synchronously. So after:

bluetoothGatt.readCharacteristic(characteristic);

you should wait callback

public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)

So if you want to do something like you describe, make something like that:

List<BluetoothGattCharacteristic> characteristics = new ArrayList<>();
boolean isGettingDeviceInformation;
int count = 0;

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    String value = characteristic.getStringValue(0);
    Log.e("TAG", "onCharacteristicRead: " + value + " UUID " + characteristic.getUuid().toString() );
    if(isGettingDeviceInformation) {
        if(count < characteristics.size()) {
            count++;
            bluetoothGatt.setCharacteristicNotification(characteristics.get(count), true);
            bluetoothGatt.readCharacteristic(characteristics.get(count));
        } else {
            isGettingDeviceInformation = false;
        }
    }
}

private void getDeviceInformation() {
    BluetoothGattService deviceInfoService = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE);
    BluetoothGattCharacteristic deviceSerialNumber, deviceHardwareRevision, deviceSoftwareRevision;
    characteristics = bluetoothGatt.getService(UUIDs.DEVICE_INFORMATION_SERVICE).getCharacteristics();
    bluetoothGatt.setCharacteristicNotification(characteristics.get(count), true);
    bluetoothGatt.readCharacteristic(characteristics.get(count));
}

UPDATE

Don't forget about that in bluetooth your operations can gone, so you can stack in loop, for waiting callback. So to avoid it, u need to make timeout on operation, so if don't get callback, you just cancel current operation, and can go further.

HeyAlex
  • 1,666
  • 1
  • 13
  • 31
  • Thanks for the answer. It really helped. I used the synchronized object for this case. i.e `code` synchronized (object) { object.wait(); } – Kshitij Nov 22 '17 at 08:59