Android 4.3蓝牙低功耗不稳定

问题描述 投票:185回答:5

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

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

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

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


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

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

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

Failed Attempt 2 - 我甚至无法发现服务/特征的例子。


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

android bluetooth bluetooth-lowenergy android-bluetooth android-4.3-jelly-bean
5个回答
175
投票

Important implementation hints

(由于Android OS更新,可能不再需要其中一些提示。)

  1. 一些设备,如Nexus 4与Android 4.3 take 45+ seconds to connect using an existing gatt instance。解决方法:始终在断开连接时关闭gatt实例,并在每个连接上创建一个新的gatt实例。
  2. 别忘了打电话给android.bluetooth.BluetoothGatt#close()
  3. onLeScan(..)中启动一个新线程然后连接。原因:BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)总是失败,如果在三星Galaxy S3与Android 4.3的同一个线程中调用LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)(至少对于构建JSS15J.I9300XXUGMK6)
  4. Most devices filter advertising
  5. 最好不要使用带有参数的android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback)来过滤某些服务UUID,因为这在三星Galaxy S3中完全打破了Android 4.3和doesn't work for 128bit UUIDs
  6. Gatt总是可以一次处理一个命令。如果几个命令被一个接一个地调用,第一个被取消due to the synchronous nature of the gatt implementation.
  7. 我经常在使用Android 5的现代设备上看到,Wifi会干扰蓝牙,反之亦然。作为最后的手段,关闭wifi以稳定蓝牙。

初学者教程

这个视频教程可以为新手提供一个非常好的切入点:为Android http://youtu.be/x1y4tEHDwk0开发蓝牙智能应用程序

下面描述的问题和解决方法现在可能已由OS更新修复

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

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

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

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

15
投票

Turning WIFI OFF:

我也可以确认,关闭WIFI会使蓝牙4.0更稳定,特别是在谷歌Nexus上(我有一台Nexus 7)。

The problem

是我正在开发的应用程序需要WIFI和连续蓝牙LE扫描。所以关闭WIFI对我来说是没有选择的。

此外我已经意识到,连续蓝牙LE扫描实际上可以杀死WIFI连接并使WIFI适配器无法重新连接到任何WIFI网络,直到BLE扫描开启。 (我不确定移动网络和移动互联网)。 这肯定发生在以下设备上:

  • Nexus 7
  • 摩托罗拉Moto G.

然而,使用WIFI进行BLE扫描似乎非常稳定:

  • 三星SCH
  • HTC One

My workaround

我扫描BLE一小段时间3-4秒然后我关闭扫描3-4秒。然后再次开启。

  • 显然,当我连接到BLE设备时,我总是关闭BLE扫描。
  • 当我从设备断开连接时,我重新启动BLE(关闭适配器然后再打开)以重新启动扫描,然后再次开始扫描。
  • 当发现servicescharacteristics失败时,我也重置了BLE。
  • 当我从应用程序应连接的设备获取广告数据时(假设500次无法连接 - 这大约是5-10秒的广告)我再次重置BLE。

6
投票

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

我将在几天内更新此答案,当我测试服务发现和gatt读取和写入请求而不重新启动时。

编辑:事实证明我正在测试开发固件版本(我们的传感器),如果没有配对就会导致问题。我们最新的生产固件版本在2540s和2541s上运行良好。

编辑:我注意到在Nexus 7 2013上,当WiFi关闭时,连接更加稳定。我想知道这是否有助于其他任何人。

编辑:我似乎已经配对了倒退。没有配对时一切正常。配对后,我遇到与OP完全相同的症状。目前还不知道这是否与我们的固件或Android BLE API有关。测试时要小心,因为一旦配对,由于本post中的3b中解释的错误,您可能无法取消配对。


4
投票

在某些型号中存在缺陷:https://code.google.com/p/android/issues/detail?id=180440

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

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

0
投票

我面临着类似的问题。我的修复是

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

断开后呼叫关闭。

© www.soinside.com 2019 - 2024. All rights reserved.