Skip to content
Advertisement

BluetoothGattCallback onCharacteristicRead never called back

I’m still trying hard to read from a BLE device (laser meter) from an android (using java) Basically I’m trying to get which fields are those I’m interested into (aka the measures)

So far i discovered 5 services (i found the usage here):

  • 3ab10100-f831-4395-b29d-570977d5bf94 (I can’t figure out what is this bad boy usage)
  • 0x1800 -> probably the ones I’m looking for
  • 0x1801 -> idk (only writable characteristics so idc)
  • 0x180a -> device name (I am able to read the name from this one)
  • 0x180f -> battery

the first problem i met is that, according to the documentation, onCharacteristicRead(3) is deprecated since API 13 as it adds now an array of byte as parameter. But according to Android studio, this overload does not exist.

The second one is that onCharacteristicRead is only called one despite calling him on more than 10 READABLE characteristics

I’m only testing things out for now but here’s what I did:

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        for (BluetoothGattService serv: gatt.getServices()) {
            System.out.println("-----------------" + serv.getUuid());
            
            for(BluetoothGattCharacteristic chara: serv.getCharacteristics()) {
                
                if((chara.getProperties() & PROPERTY_READ) != 0) {
                    System.out.println("Can read");
                    gatt.readCharacteristic(chara);
                } 
                else {
                    System.out.println("Can't read");
                }
            }
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,  int status) {
        super.onCharacteristicRead(gatt, characteristic, status);
        System.out.println("Called");

        if(status == GATT_SUCCESS) {
            System.out.println(new String(characteristic.getValue()));
        } else {
            System.out.println("error during read");
        }
    }

And this is the output:

    I/System.out: -----------------00001800-0000-1000-8000-00805f9b34fb
    I/System.out: Can read
    I/chatty: uid=10168(com.example.adici) Binder:27154_2 identical 1 line
    I/System.out: Can read
    I/System.out: -----------------00001801-0000-1000-8000-00805f9b34fb
    I/System.out: Can't read
    I/System.out: -----------------3ab10100-f831-4395-b29d-570977d5bf94
    I/System.out: Can read
    I/System.out: Can read
    I/System.out: Can't read
    I/System.out: Can read
    I/System.out: Can read
    I/System.out: -----------------0000180f-0000-1000-8000-00805f9b34fb
    I/System.out: Can read
    I/System.out: Can read
    I/System.out: -----------------0000180a-0000-1000-8000-00805f9b34fb
    I/System.out: Can read
    I/System.out: Called
    I/System.out: DISTO 80951028

I’ve also tried adding this while loop to wait for the last callback to happen before starting another one as it was mentionned

while(waitingForCallback)
{
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
waitingForCallback = true;
gatt.readCharacteristic(chara);

Where waitingForCallback is set to false in onCharacteristicRead but it ends up in infinite loop as the method is not called

I really don’t get why the overload is a problem for my IDE as Sdkmin = 27 and targetSdk = 31

Any help is appreciated !

Advertisement

Answer

You may not initiate a gatt operation (for example reading a characteristic) while an operation is already pending. You must wait for the callback before you initiate the next read.

You sleep loop won’t work since the Bluetooth stack never calls a callback of yours while another callback is already running. In this case if you run that sleep loop in onServicesDiscovered, the onCharacteristicRead callback will be scheduled to run, but it won’t run until onServicesDiscovered has returned. This is a feature of the “Binder” mechanism in Android, which prevents callbacks for the same object to run concurrently.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement