1
votes

Does anyone know how to discover a BLE Service by UUID in Android? There is a discoverServices() method in Android, but there seems to be no way to discover one individual Service instead of all of them. In Bluetooth, discovering all Services takes a 'long' time, whereas discovering individual Services based on UUID does not take as long. It takes even longer for Android because Android also discovers all the Characteristics and Descriptors as well.

1

1 Answers

1
votes

TL;DR: you can't - if you don't want to do some really ugly and potentially dangerous hack.

There is no easy way to do this. If you look at what discoverServices() does on Nougat, you'll see it calls GattService:L1454.

void discoverServices(int clientIf, String address) {
    enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
    Integer connId = mClientMap.connIdByAddress(clientIf, address);
    if (DBG) Log.d(TAG, "discoverServices() - address=" + address + ", connId=" + connId);
    if (connId != null)
        gattClientSearchServiceNative(connId, true, 0, 0);
    else
        Log.e(TAG, "discoverServices() - No connection for " + address + "...");
}

The key here is gattClientSearchServiceNative:

gattClientSearchServiceNative(int conn_id, 
                              boolean search_all, 
                              long service_uuid_lsb, 
                              long service_uuid_msb)

If search_all is true, it will scan everything. If not, it will search only a service with the provided UUID and its characteristics and descriptors.

You could actually try and use reflection to call this directly passing a false search_all parameter and a valid UUID, but that's a really bad practice and will end up crashing when a new version comes out and the internal implementation of this class changes.