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

Gatt client leaks in Android BLE

I'm developing an application for Android that connects to my nRF52832-based product. I'm using the Nordic Android-BLE-Library. I don't believe this issue has as much to do with the Nordic chip specifically as Android BLE in general.

Has anyone else run in to Gatt client leaks when developing an Android application? After a certain period of using my application, I start getting messages about "Max gatt client reached: 32", and then pretty much every BLE operation (scanning, connecting) fails after that -- connection with that mysterious error 133. The phone I'm developing on is a Google Pixel 3, but I think this issue might affect other phones as well.

My usage of BLE might be somewhat nontraditional. My app is continuously scanning in the background for BLE devices and connecting to them. In some circumstances, it may repeatedly connect to a device, read a serial number, and then disconnect. Assuming I'm doing something wrong in cleaning up those connections, that would explain the "max gatt client reached" issue.

One note about my usage of the Nordic library that might affect things is I'm re-using BleManagers. I maintain a BleManager for a specific device, and if a link loss occurs I maintain that BleManager in memory. If I then pick that device up again in a scan, I'll re-use the BleManager and reconnect to it. I'm using the connect method -- specifically, connect().retry(2, 1500).useAutoConnect(false).timeout(10 * 1000L). I'm using the context.getBluetoothAdapter().getRemoteDevice(address) method to get a BluetoothDevice to pass to this method, based on a String bluetooth address I receive from my scanning. Initially I re-used this BluetoothDevice between connections, but I found that was causing issues to I get a fresh BluetoothDevice object on each connection attempt.

Referring to my usage pattern of connecting to a device, reading a serial number, and possibly disconnecting -- the way I'm doing that is in my BleManagerGattCallback initialize() method, I read device information characteristics and then call the BleManager.disconnect() method.

Another note about my usage: I've wrapped most of the BleManager methods with Kotlin coroutine wrappers, so I can write my code in a coroutine style. I don't think this should affect anything though, given my understanding of how the BleManager class executes everything serially in the UI thread anyway.

I hope these are enough details that someone with more experience can perhaps point out a flaw in my methodology our give me some debugging tips here.

Thanks very much!

  • Hi 

    We have seen at least one report of something similar, where Android would complain if you disconnected 32 times without explicitly calling disconnect() in the Android app (like if the peripheral device disconnects, or there is a link loss). 

    Are you able to use the log output and count the number of calls to gattConnect() ? 

    If the difference between calls to gattConnect() and calls to disconnect() is 32, and the issue occurs, it is most likely the same problem. 

    Best regards
    Torbjørn

Related