小编典典

Android 4.3 低功耗蓝牙不稳定

all

我目前正在开发一个使用蓝牙低功耗的应用程序(在 Nexus 4 上测试)。在开始使用 Android 4.3 中的官方 BLE API
后,我注意到在我第一次连接设备后,我很少能够再次成功连接/通信该设备或任何其他设备。

按照此处的指南,我可以成功连接到设备、扫描服务和特征以及读/写/接收通知,而不会出现任何问题。但是,断开连接并重新连接后,我经常无法扫描服务/特征或无法完成读/写。我在日志中找不到任何内容来说明为什么会发生这种情况。

一旦发生这种情况,我必须卸载应用程序,禁用蓝牙,然后重新启动手机,然后它才能再次开始工作。

每当设备断开连接时,我都会确保在 BluetoothGatt 对象上调用 close() 并将其设置为 null。有什么见解吗?


编辑:
日志转储:对于这些日志,我将手机植根并提高了 /etc/bluetooth/bt_stack.conf 中相关项目的跟踪级别

成功连接-
重新启动手机并安装应用程序后首次尝试。我能够连接、发现所有服务/特征以及读/写。

失败的尝试 1 -
这是从上述成功连接断开后的下一次尝试。似乎我能够发现特征,但第一次尝试读取返回了一个空值,此后很快就断开了连接。

失败的尝试 2 - 我什至无法发现服务/特征的示例。


编辑 2:
我尝试连接的设备基于 TI 的 CC2541 芯片。我获得了一个TI
SensorTag
(也是基于 CC2541)来玩,发现 TI昨天发布了一个用于 SensorTag的 android
应用程序。
但是,这个应用程序也有 同样的问题。 我在另外两台 Nexus 4 上对此进行了测试,结果相同:第一次或第二次连接到
SensorTag 成功,但(根据日志)此后未能发现服务,导致各种崩溃。我开始怀疑这个特定芯片是否有问题?


阅读 107

收藏
2022-07-18

共1个答案

小编典典

重要的实施提示

(也许由于 Android 操作系统更新,其中一些提示不再需要。)

  1. 某些设备(例如 Nexus 4 和 Android 4.3需要 45 多秒才能使用现有 gatt 实例进行连接)。解决方法:始终在断开连接时关闭 gatt 实例,并在每次连接时创建一个新的 gatt 实例。
  2. 别忘了打电话android.bluetooth.BluetoothGatt#close()
  3. 在里面启动一个新线程 onLeScan(..),然后连接。原因:BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)总是失败,如果LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)在带有 Android 4.3 的三星 Galaxy S3 上的同一线程中调用(至少对于构建 JSS15J.I9300XXUGMK6)
  4. 大多数设备过滤广告
  5. 最好不要使用 android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) 该参数来过滤某些服务 UUID ,因为这在带有 Android 4.3 的三星 Galaxy S3 中完全被破坏,并且通常不适用于 128 位 UUID
  6. Gatt 始终可以一次处理一个命令 。如果几个命令一个接一个地被调用,由于 gatt 实现的同步特性,第一个命令会被取消。
  7. 即使在装有 Android 5 的现代设备上,我也经常看到 Wifi 会干扰蓝牙,反之亦然。 作为最后的手段,关闭 wifi 以稳定蓝牙。

下面描述的问题和解决方法现在可能已通过操作系统更新修复

解决方法:我可以“稳定”我的应用程序这样做......

  1. 我为用户提供了“重启蓝牙”设置。如果启用了该设置,我会在某些点重新启动蓝牙,这表明 BLE 堆栈的开始变得不稳定。例如,如果 startScan 返回 false。如果 serviceDiscovery 失败,也可能是一个好点。我只是关闭和打开蓝牙。
  2. 我提供了另一个设置“关闭 WiFi”。如果启用了该设置,我的应用会在应用运行时关闭 Wifi(然后再将其重新打开)

这项工作是基于以下经验......

  • 在大多数情况下,重启蓝牙有助于解决 BLE 问题
  • 如果您关闭 Wifi,BLE 堆栈会变得更加稳定。但是,它在大多数打开 wifi 的设备上也能正常工作。
  • 如果您关闭 Wifi,重新启动蓝牙可完全恢复 BLE 堆栈,而在大多数情况下无需重新启动设备。
2022-07-18