2

I'm trying to read a value from a custom characteristic in a custom service on a BLE device. I successfully call the readCharcteristic method as it returns true. However, the onCharacteristicRead callback function is never invoked. I am unable to determine why this is so.

My read function is as follows (there is no pending or ongoing read or write request when this method if called) -

fun readOneSpecificCharacteristic() {

    if (lpnInfoChar?.isReadable() == true) {
    
        Log.i("READ", "READABLE")
    
        if (btGatt?.readCharacteristic(lpnInfoChar) == true) {
            Log.i("READ", "INIT SUCCESS") //<- my code reaches here
        } else {
            Log.i("READ", "INIT FAIL")
        }
    
    } else {
        Log.i("READ", "NOT READABLE")
    }
}

My Callback (which is never invoked) -

private val gattCallback = object: BluetoothGattCallback() {

    override fun onCharacteristicRead(
        gatt: BluetoothGatt,
        characteristic: BluetoothGattCharacteristic,
        value: ByteArray,
        status: Int
    ) {
    
        Log.i("Callback", "onCharacteristicRead")
    
        with(characteristic) {
            when (status) {
                BluetoothGatt.GATT_SUCCESS -> {
                    Log.i("BluetoothGattCallback", "Read characteristic $uuid:\n${value.toHexString()}")
                }
                BluetoothGatt.GATT_READ_NOT_PERMITTED -> {
                    Log.e("BluetoothGattCallback", "Read not permitted for $uuid!")
                }
                else -> {
                    Log.e("BluetoothGattCallback", "Characteristic read failed for $uuid, error: $status")
                }
            }
        }
    }
}

The other callbacks work as expected - I am able to write, read rssi value, discover service etc.

Additionally, I know that the BLE device is working fine since BLE scanning apps form the PlayStore are able to read the value from it.

Where gattCallback is registered -

override fun onScanResult(callbackType: Int, result: ScanResult) {

            if (isScanning) {
                stopScan()
            }

            with(result.device) {
                Log.i("ScanCallback", "Found BLE device! Name: ${name ?: "Unnamed"}, address: $address")
                setGeneralStatusText("BLE Device Found - ${name ?: "Unnamed"}")

                Log.i("ScanResultAdapter", "Connecting to $address")
                setGeneralStatusText("Connecting to ${name ?: "Unnamed"} - $address")
                connectGatt(baseContext, true, gattCallback, BluetoothDevice.TRANSPORT_LE)
            }
        }
K K
  • 73
  • 6
  • Could you post the code where you register `gattCallback`? Are you making sure that you're only reading one characteristic at any time and waiting for its result, as BLE does not support multiple read requests at the same time? – Daniel F Dec 21 '22 at 13:09
  • @DanielF I am definitely reading only one characteristic at a time with no ongoing read or write request. I am updating the question with the code requested. – K K Dec 21 '22 at 13:12
  • I don't know, I'm sorry. – Daniel F Dec 21 '22 at 13:28
  • Is it possible that you read characteristic before the connection is ready? – Kozmotronik Dec 21 '22 at 14:18
  • @DanielF I found the issue. Please see my posted answer. – K K Dec 21 '22 at 14:37
  • @Kozmotronik I found the issue. Please see my posted answer. – K K Dec 21 '22 at 14:38
  • 2
    Good one @KK. I upvoted both your question and answer. You made me note about those API changes for Android 13. Hence I'm gonna update my projects soon. – Kozmotronik Dec 21 '22 at 15:16

1 Answers1

3

Turns out the deprecated method needed to be called. More info here -

New `onCharacteristicRead` method not working

K K
  • 73
  • 6