Android:自动重新连接 BLE 设备

标签 android bluetooth-lowenergy android-bluetooth

我的目标是让 Android 设备重新连接到它之前连接过的 BLE 设备无需用户干预,就像它对经典 BT 配对设备所做的那样(甚至可以通过电源循环)。

BTLE 设备的理念之一是保存服务、绑定(bind)和启用状态,以便重新连接非常快并且在外围设备上消耗的电量非常少。

我所做的似乎有效,但效果不佳。

第一步是连接或配对并连接到新设备,将“autoconnect”参数设置为“true”。 当设备断开连接时,不要调用 gatt.close()。我到处都看到应该调用 gatt.close()。但是如果我调用 gatt.close() Android 中央应用程序永远不会重新连接。这个我已经测试过很多次了。

如果我没有调用 gatt.close() 并且没有重启 Android,自动连接通常会发生。有时可能需要很长时间,尤其是在 5.0 版本之后。然而,它是不可靠的,并且由于非常低负载的扫描周期和设备在扫描周期实际检测到广告之前退出广告而可能是不可靠的。我不确定,因为没有办法像有广告一样检测扫描操作!扫描也可能在一定时间后停止,但没有相关文档。

所以我认为我需要做的是以某种方式将 Android 使用的背景扫描率设置为更高的占空比(仅在 5.0 及更高版本中可能)当自动连接已设置但我不知道如何做这个。我不想开始自己的扫描,而是以某种方式设置 Android 用于重新连接的后台扫描速率。有谁知道如何做到这一点?有谁真的知道 autoconnect 和 gatt.close() 是如何工作的?

也许自动连接并不意味着像我上面指出的那样重新连接?

最佳答案

经过多次试验和磨难,这就是我让 Android 自动连接的最佳方式,唯一的用户操作是首先选择设备(如果使用设置菜单,然后首先配对)。

您必须在 BroadcastReceiver 中捕获配对事件并执行 BluetoothDevice.connectGatt() 将自动连接设置为 true。然后当设备断开连接时,调用 gatt.connect()。

更新:虽然上述方法一般有效,但有时速度慢得令人痛苦,这可能是因为挂起的连接使用了极其保守的扫描速率。另一个缺点是,对于每个你想要自动重新连接的设备,你必须保持一个 BluetoothGatt 对象执行挂起的连接。在嵌入式世界中,这是疯狂的。相反,人们所做的是通过检查其广告来不断扫描并连接到所需的设备。一个只保存关于设备的最少量数据(服务、配对状态和 key 等)。捕获广告后,您会看到它是否是您已知的设备之一,如果是则连接。 我在 Android 上尝试了等效的方法。始终扫描(低功率)并连接到感兴趣的广告,并维护一个代表已知设备的类。这种方法有一些烦人的细节(比如在连接时关闭扫描并在连接后重新启动)但它基本上可以在没有维护连接开销的情况下工作。但是有一个异常(exception)我不明白。一台预配对设备的广告永远不会被扫描仪看到。但是,如果我调用与此设备的挂起连接,我会重新连接。我完全不明白这一点。在我的嵌入式平台上,它可以正常工作。 如果有人尝试过这种自动重新连接的方法,请分享您的经验!

我发现了预配对设备未被 Android 识别的原因。 Android 仅在设备响应扫描请求时报告扫描结果。配对后,此设备仅发出广告并忽略扫描请求,因此 Android 系统不会在 ScanCallback 中传递其广告。因此,为了使用扫描方法工作,我必须对那些特定设备使用挂起连接方法。看起来你赢不了!

============= 2020 年更新

许多年过去了,我对后台扫描方法有了更多的经验。如果将支持的平台保持在 5 及更高版本,则可以仅使用最新的扫描器 API 并使用过滤器,从而无需自己解码原始广告。我还发现,如果您在连接时不关闭扫描,连接和重新连接会更快。我知道这违反了所有文档,但它有效并且在某些平台上允许发生连接,否则不会发生连接。此外,到目前为止,我只发现一个(健康)设备需要挂起连接。免责声明:我只使用过健康设备。

关于Android:自动重新连接 BLE 设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34425662/

相关文章:

ios - 应用程序未运行时监听信标

c++ - <<(按位左移)对 Swift 中的数组有什么作用?

android - 带有广播接收器的工作管理器在应用程序关闭时不起作用

android - 从 dialogfragment 发布新数据后更新 Listview

android - 内容 ://mms-sms/conversations/return NullPointerException at Android ICS Samsung

Android - 指纹信息存储在设备中的位置和安全程度

java - 如何仅扫描广告包 BLE

android - 如何将自定义日志发送到 Google Play 开发者控制台?

ios - 在 iOS 上检测非 iBeacon 信标?

android - 现在不推荐使用 BluetoothAdapter.getDefaultAdapter() 我该使用什么?