1

I am developing an Android app (API 23+) that communicates via BLE with a device. There is no pairing / bonding involved.

The happy path of the interaction is that the app connects then sends a message to the device, and the device in turn sends a reply back, then they both disconnect.

While characterizing strange behavior I asked in Android BLE unexpectedly reconnects potentially from PBAP / MAP Bluetooth profiles, I created a simple service to monitor low-level bluetooth connections; it listens for broadcasts of BluetoothDevice.ACTION_ACL_CONNECTED and BluetoothDevice.ACTION_ACL_DISCONNECTED.

While most of the time the connect / disconnect corresponds well between app and device, sometimes the app receives a disconnect notification that can be ~5-20 seconds after both the app and device have closed the connection. I have verified that the device actually closed, and the app logs all show the system properly shutting down the connection.

In these instances, if the app tries to connect again with the device before ACL_DISCONNECTED is broadcast, it will either receive an error or the subsequent connect request is queued and kicked off after the ACL_DISCONNECTED broadcast.

This does not seem to be specific to devices --- I test with a variety of makes and models --- nor the API version (23-25).

  • Is this known (expected) behavior?
  • Are there ways to mitigate this issue?...to ensure the disconnect indeed happens in a timely manner?
  • Is there a more direct way --- e.g., through an API call --- to tell if the connection is still up, as opposed to receiving ACL-related broadcasts?
Community
  • 1
  • 1
Steve Yohanan
  • 757
  • 5
  • 17

1 Answers1

2

If the BLE devices stops broadcasting instead of sending disconnect signal this issue happens. If the BLE device didn't send the disconnect signal Android device thinks the that the connection is open and it waits for sometime (5-20 sec) and then calls onconnectionstatechange() with time out status code. If you can make the BLE device send the disconnect signal instead of stop broadcasting it should fix the issues. Hope this helps

Avinash4551
  • 220
  • 1
  • 9
  • thanks for the reply @Avinash4551. in my specific case, the app (central) initiates the disconnect; the peripheral does not disconnect until the app has. – Steve Yohanan Apr 06 '17 at 21:19
  • did you call gatt.disconnect() ? in your android code. It should immediately disconnect the current connection – Avinash4551 Apr 06 '17 at 21:34
  • I use [RxAndroidBle](https://github.com/Polidea/RxAndroidBle), which manages the lower-level unwinding of the connection when we unsubscribe from the Observable. From what I see in the logs, it seems as if they are calling BluetoothGatt.close() as opposed to disconnect(). I'll verify what exactly they do. `04-07 09:19:31.882 14506-14506/? D/BluetoothGatt: close() 04-07 09:19:31.883 14506-14506/? D/BluetoothGatt: unregisterApp() - mClientIf=5` – Steve Yohanan Apr 07 '17 at 13:22
  • I also have a more simplified test app that has similar but very reduced functionality. this test app employs direct Android API calls to BT, so I know I explicitly call BluetoothGatt.disconnect(). I experience similar issues, from time to time, with the ACL_DISCONNECTED notification being delayed by ~5-20 secs. – Steve Yohanan Apr 07 '17 at 15:50
  • I have not used RxAndroidBle Library and I'm not sure how gatt.disconnect() works in your case. I have seen that other users are also reporting same issue that lib is telling the app that disconnect happened after 5-20 seconds. I used gatt.disconnect() which disconnects immediately. Sorry, I couldn't be of much help. – Avinash4551 Apr 07 '17 at 16:06