Android BLE GATT 断开连接 vs. 设备断开连接

3
我正在开发一款与自定义蓝牙设备进行通信的Android应用程序。 在调用BluetoothGatt.Disconnect()后,我发现OnConnectionStateChange回调被调用,并且新状态为Disconnected,但是,实际上设备断开连接的时间似乎有点滞后。例如,如果我使用已连接的设备调用BluetoothManager.GetConnectionState(...),它仍然会返回Connected。有时需要几秒钟才能使GetConnectionState返回Disconnected。这种情况正常吗?我是否在我的应用程序中做错了什么导致这种情况发生?例如从非UI线程断开连接之类的问题?或者,物理蓝牙设备本身是否无法正确处理断开连接事件并可能未能及时完成断开连接?
2个回答

4
Android的BLE系统很混乱。我看到了您所描述的情况,但更糟的是,在Android断开连接后,它在幕后与您的外设保持持久连接。
通常需要30秒才能最终断开连接,有时需要几分钟!这完全取决于您当时使用的手机型号。
如果您有能力的话,我强烈建议向外设添加一个断开特性,这样您可以通过编写断开请求来实现真正的断开,并让外设强制断开连接,然后让Android接管。
我见过的好处是总是有效的(因为Android总是会检测到“硬”断开连接,而“软”断开请求可能会在某些手机上引起一些问题)。通常,“好”的手机不会表现出这种行为(尤其是Marshmallow及以上版本),但回到KitKat时代……哇……
另一个好处是……如果您使用iOS,您可以更快地扫描或重新连接已断开的外设。

1
当您调用“disconnect()”时,只会断开与客户端对象(BluetoothGatt对象)的连接。您可以将多个BluetoothGatt对象连接到同一物理设备上。多个应用程序也可以连接到同一设备上拥有自己的BluetoothGatt对象。
一旦您调用“disconnect()”,请求将在系统中的蓝牙堆栈中处理,并且在完成请求处理后立即调用您的应用程序中的onConnectionStateChange回调函数。但是,在所有其他客户端断开连接之前,它不会断开链接。较新版本的Android还会延迟几秒钟进行物理断开连接(不确定原因)。此外,一旦已将断开连接请求发送到蓝牙控制器,实际断开连接可能需要一些时间,因为远程设备需要确认断开连接(或超时)。默认超时时间为20秒,直到最近在最新的Android版本中更改为5秒。

谢谢澄清。您知道在设备实际断开连接时是否可以获得回调事件吗? - PICyourBrain
只需注册广播接收器以侦听 https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_ACL_DISCONNECTED。 - Emil
嗨,我在Android 12设备上遇到了同样的断开连接问题。对于你提出的解决方案,我仍然没有理解透彻。能否请你详细说明一下? - Rishabh Gupta
到底什么是不清楚的? - Emil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接