安卓4.3低耗电蓝牙不稳定

我目前正在开发一个使用低耗电蓝牙的应用程序(在 nexus4上进行测试)。在开始使用 Android 4.3中的官方 BLAPI 之后,我注意到在第一次连接一个设备之后,我很少能够再次成功地连接到该设备或任何其他设备。

遵循 给你指南,我可以成功地连接到一个设备,扫描服务和特性,读/写/接收通知,没有任何问题。然而,在断开连接和重新连接之后,我常常无法扫描服务/特性,或者无法完成读/写。我在日志里找不到任何关于这一切发生的原因。

一旦发生这种情况,我必须卸载应用程序,禁用蓝牙,并重新启动手机之前,将重新开始工作。

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


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

成功连接 -重启手机并安装应用程序后的第一次尝试。我能够连接,发现所有的服务/特性,读/写。

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

失败的尝试2 -一个我甚至不能发现服务/特性的例子。


编辑2:
我试图连接的设备是基于 TI 的 CC2541芯片。我得到了一个 TI 传感器标签(也是基于 CC2541)来玩玩,发现 TI 昨天为 SensorTag 发布了 一个安卓应用程序。然而,这个应用程序有 同样的问题。,我在另外两个 Nexus 4上测试了它,得到了相同的结果: 连接到 SensorTag 的第一次或第二次是成功的,但是(根据日志)之后没有发现服务,导致了各种各样的崩溃。我开始怀疑是不是这个芯片出了问题?

101271 次浏览

确保您的 Nexus 与该设备配对。我无法验证通信是否正常工作,但您可以连接不止一次而无需重新启动。似乎第一个连接不需要配对,但是所有后续尝试都需要。

几天后,当我测试服务发现和 gatt 读写请求而无需重新启动时,我将更新这个答案。

编辑: 事实证明,我正在测试一个开发固件版本(我们的传感器) ,如果没有配对,就会导致问题。我们最新的生产固件建立工程2540年代和2541年罚款。

编辑: 我确实注意到,在 Nexus72013上,当 WiFi 关闭时,连接更加稳定。我想知道这对其他人有没有帮助。

编辑: 我好像把配对搞反了。不配对的时候一切都很好。配对之后,我出现了和手术相同的症状。只是还不知道这是否与我们的固件或 Android BLAPI 有关。如果要测试这个,请小心,因为一旦配对,您可能无法解除配对,因为在这个 邮寄的3b 中解释了一个错误。

重要的实现提示

(也许由于 Android 操作系统的升级,这些提示已经没有必要了。)

  1. 有些设备像 Nexus 4搭载了 Android 4.3 使用现有的 gatt 实例连接需要45秒以上。解决方法: 总是在断开连接时关闭 gatt 实例,并在每个连接上创建 gatt 的新实例。
  2. 别忘了打电话给 android.bluetooth.BluetoothGatt#close()
  3. onLeScan(..)中启动一个新线程,然后连接。原因: 如果在使用安卓4.3的同一个线程中在 LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)内部调用 Samsung Galaxy S III (至少在构建 JSS15J.I9300XXUGMK6时) ,那么 BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)总是会失败
  4. 大多数设备过滤广告
  5. 最好不要使用 android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback) 使用要筛选特定服务 UUID 的参数,因为这与 Android 4.3和 不适用于128位 UUID的 Samsung Galaxy S III 完全不同。
  6. Gatt 总是可以一次处理一个命令 。如果一个又一个命令被调用,第一个命令就会因为 gatt 实现的同步性而被取消。
  7. 我经常看到甚至在安卓5的现代设备上,Wifi 干扰蓝牙,反之亦然

初学者教程

对于新手来说,一个相当不错的切入点可以是这个视频教程: 为 Android http://youtu.be/x1y4tEHDwk0开发蓝牙智能应用程序

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

解决办法: 我可以“稳定”我的应用程序做到这一点..。

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

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

  • 在大多数情况下,重新启动蓝牙可以帮助解决 LE 问题
  • 如果关闭 Wifi,BLE 栈将变得更加稳定。然而,它在大多数打开 wifi 的设备上也能正常工作。
  • 如果关闭 Wifi,重新启动蓝牙在大多数情况下不需要重新启动设备就可以完全恢复 ABLE 堆栈。

关掉 WIFI:

我也可以证实,关闭 WIFI 让蓝牙4.0更加稳定,尤其是在谷歌 Nexus (我有一个 Nexus 7)上。

问题是

是应用程序,我正在开发的 需求WIFI和连续 蓝牙扫描。所以关掉 WIFI 对我来说没有选择余地。

此外,我已经认识到,连续蓝牙 LE 扫描实际上可以 切断 WIFI 连接和使 WIFI 适配器无法重新连接到任何 WIFI 网络,直到布尔扫描是打开的。(我对移动网络和移动互联网不是很确定)。
这种情况肯定发生在以下设备上:

  • Nexus7
  • 摩托罗拉 Moto G

然而,WIFI 上的 BLE 扫描似乎相当稳定:

  • 三星 S4
  • HTC One

我的变通办法

扫描一个短期的时间 3-4秒然后我 关闭扫描3-4秒。然后再上。

  • 显然,当我连接到一个 BLE 设备时,我总是关闭 ABLE 扫描。
  • 当我断开与设备的连接时,我重新启动 BLE (关闭适配器,然后打开) ,以便在再次开始扫描之前重新设置堆栈。
  • 当发现 servicescharacteristics失败时,我还重置了 BLE。
  • 当我从应用程序应该连接的设备获得广告数据时(比如说500次无法连接——大约是5-10秒的广告时间) ,我再次重置 BLE。

在一些模型中,存在一个缺陷: Https://code.google.com/p/android/issues/detail?id=180440

另一方面,在我的情况下,问题是,我的连接没有在 onDestroy 方法中正确关闭。正确关闭后,问题对我来说是不存在的,无论是打开或关闭无线网络。

btGatt.disconnect();
btGatt.close();

我也遇到过类似的问题,我的解决办法是

if (Build.VERSION.SDK_INT >= 23) {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
} else {
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
}

(断开连接后关闭)。