BLE service is not found by UUID (the UUID is correct in the code)

1 day ago 3
ARTICLE AD BOX

I had started this BLE project in Python, ran into problems with android permissions, so I had a go at (I'll be honest... vibe) coding a native Kotlin android app. The main part of it is to run a thread that will repeatedly poll a specific characteristic by id and send the data by UDP.

So far, it's finding and connecting to the device:

val device = bluetoothAdapter.getRemoteDevice(targetDeviceAddress) bluetoothGatt = device.connectGatt(context, false, gattCallback)

That is triggering onConnectionStateChange(). I know this is happening because the Bluetooth device responds at this point.

This calls gatt.discoverServices(), which triggers onServicesDiscovered():

override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { if (status == BluetoothGatt.GATT_SUCCESS) { val service = gatt.getService(UUID.fromString(targetServiceUuid)) if (service != null) { targetCharacteristic = service.getCharacteristic(UUID.fromString(targetCharacteristicUuid)) _status.value = BleStatus.Connected } else { _status.value = BleStatus.Error("Service not found") } } else { _status.value = BleStatus.Error("Service discovery failed") } }

I know it's entering this function because "Service not found" flashes in the app's status box. This is the only place where this string is found -- so it is definitely trying to get the service (based on targetServiceUuid, which I've verified by listing the device's services), and it isn't found.

That is -- as far as I know, I'm requesting a correct service UUID, but nothing is coming back, and I'm out of ideas.

The app is also requesting Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT and Manifest.permission.ACCESS_FINE_LOCATION permissions before this (and I checked the apps permissions in the settings -- it does have "location" and "nearby devices," so I believe the failure isn't due to insufficient permissions).

It's a OnePlus (Oppo) phone with Android 14. The device is a BBC Micro:bit.

What am I missing? Thanks.

FURTHER INFORMATION:

With some more logging, I found that the micro:bit's services are being reported differently on the computer compared to the phone.

Leaving out irrelevant results, a python+bleak script running on the computer reports that e95d0753-251d-470a-a062-fa1922dfa9a8 (Handle: 40): MicroBit Accelerometer Service exists.

But this UUID is absent from the Android environment.

Logging Kotlin code looks like this:

val uuid = UUID.fromString(targetServiceUuid) val lsb = uuid.getLeastSignificantBits() val msb = uuid.getMostSignificantBits() Log.i("mb2o", "targetServiceUuid string = %s".format(targetServiceUuid)) Log.i("mb2o", "lsb hex = %s".format(lsb.toHexString())) Log.i("mb2o", "msb hex = %s".format(msb.toHexString())) // this is poorly factored but will delete later val srvIter = gatt.getServices().iterator() while (srvIter.hasNext()) { var srvc = srvIter.next() Log.i("mb2o", "service = %s".format(srvc.uuid)) }

and prints

targetServiceUuid string = e95d0753-251d-470a-a062-fa1922dfa9a8 lsb hex = a062fa1922dfa9a8 msb hex = e95d0753251d470a service = 00001800-0000-1000-8000-00805f9b34fb service = 00001801-0000-1000-8000-00805f9b34fb service = 0000fe59-0000-1000-8000-00805f9b34fb service = e97dd91d-251d-470a-a062-fa1922dfa9a8 service = 0000180a-0000-1000-8000-00805f9b34fb service = e95d93af-251d-470a-a062-fa1922dfa9a8

e95d93af-251d-470a-a062-fa1922dfa9a8 is a near match but corresponds to the micro:bit event service, not the accelerometer.

A puzzling result. Well, maybe the event service will work for this.

Read Entire Article