This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Android: Read characteristic without service discovery

We are writing an Android app for our own peripheral (nRF51-based). We know the handles for all the characteristics.

On Android gatt.discoverServices() needs to be called, and wait for onServicesDiscovered(), then getServices(), before the Characteristic object is available.

This is very time-consuming, and often onServicesDiscovered() does not get called (despite connection success).

Is there a way to directly to write to an attribute handle or a characteristic UUID, bypassing all the discovery steps?

  • No, as far as I know.

    How often do you have the issue "often onServicesDiscovered() does not get called" ? Do you see that when you use our nRFConnect app ?

  • That is a very good question. I can always get the services using the nRF MCP app. In fact, after initiating connection from my app, when it gets GATT_CONNECTED, and I then switch over to MCP, it shows the peripheral as connected as well, and I can even do discover services from MCP, successfully. The Android recommended procedure is so simple (call discoverServices upon getting newState == GATT_CONNECTED in onConnectionStateChange), I don't even have any other options to try.

  • Hi, all the BLE-related method calls are listed on the Log in nRF Connect on DEBUG level. Also, I write there delays (e.g wait(600)). nRF Connect waits for 600ms after it gets connected before calling discoverServices(). Also, (IMPORTANT) if you have nRF Connect in the background (left with HOME button, or switched to another app without exiting the nRF app with a Back button), and there was the GATT server enabled (any configuration,even empty has been selected), and Settings->Connectivity->Show incoming connection is enabled (default), the nRF Connect (or any other app with GATT Server running) will "intercept" your connection on Android pre-7.0. It has been fixed in 7.0. Before, the connection could had only 1 listener for service discovery, so if you call serviceDiscovery(), then nRF calls it again, only nRF gets callback.

  • To avoid this problem:

    • make sure the nRF Connect is closed with Back button
    • disable GATT Server, or switch the option mentioned above to OFF
    • wait for ~2 sec before calling discoverServices(). In this time nRF should be ready and you should get services from cache immediately.
Related