3

I'm working on an Android app that communicates with a custom bluetooth device. After calling BluetoothGatt.Disconnect() I am seeing that the OnConnectionStateChange callback is called, and the new state is Disconnected, however, there seems to be a lag between when that happens and when the Device itself is actually disconnected. For example, if I call BluetoothManager.GetConnectionState(...) with the device that was connected, it still returns Connected. Sometimes it takes several seconds before GetConnectionState returns Disconnected. Is this normal? Is it possible that I am doing something wrong in my application that could be causing this? e.g. disconnecting from a non-UI tread, or something like that? Or, is it possible that the physical bluetooth device itself is not handling the disconnect properly and maybe not completing the disconnect event promptly?

PICyourBrain
  • 9,976
  • 26
  • 91
  • 136

2 Answers2

4

Android's BLE system is so messed up. I've seen what you've described, except much worse - where you disconnect from Android, but under the hood it maintains a persistent connection with your peripheral.

Usually takes 30 seconds to finally disconnect, sometimes takes minutes! All depending on which phone you were using at the time.

If you have the ability, I highly recommend adding a disconnection characteristic to the peripheral, so that you actually disconnect by writing a disconnection request, and letting the peripheral force the disconnection - and then Android will pick it up.

The benefit I've seen is that it ALWAYS works (because a 'hard' disconnection is always picked up by Android, whereas a 'soft' disconnection request can cause some issues on certain phones). Typically 'good' phones don't exhibit this behaviour (especially Marshmallow and on), but back in those KitKat days.... Wow....

Another benefit... If you're using iOS, you can scan for or re-connect to disconnected peripherals much faster.

SJoshi
  • 1,866
  • 24
  • 47
1

When you call "disconnect()" you only disconnect your client object (BluetoothGatt object). You can have multiple BluetoothGatt objects connected to the same physical device. Multiple apps can also have own BluetoothGatt objects connected to the same device.

As soon as you call "disconnect()" the request is processed in the Bluetooth stack in the system and it immediately then calls the onConnectionStateChange callback in your app when it has completed processing the request. However, it will not disconnect the link until all other clients have disconnected. Newer versions of Android also delay the physical disconnection a few seconds (not sure why). Also, once the disconnect request has been sent to the Bluetooth controller it may take some time to actually disconnect since the remote device needs to acknowledge the disconnection (or time out). The default time out was 20 seconds until it was recently changed to 5 seconds in the latest Android version.

Emil
  • 16,784
  • 2
  • 41
  • 52
  • Thanks for the clarification. Do you know if it's possible to get a callback event when the device actually disconnects? – PICyourBrain Jun 13 '17 at 15:43
  • Just use register a broadcast receiver to listen to https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_ACL_DISCONNECTED. – Emil Jun 13 '17 at 17:05
  • Hi, i am faing this same disconnection issue on Android 12 devices.I am still not getting this solution that you proposed. Can u please elaborate on the same . – Rishabh Gupta Jun 12 '23 at 18:33
  • Exactly what is unclear? – Emil Jun 12 '23 at 20:46