191

I am currently developing an application that will use Bluetooth Low Energy (testing on the Nexus 4). After getting started with the official BLE APIs in Android 4.3, I have noticed that after I connect a device for the first time I am rarely able to successfully connect to / communicate with that device or any other device again.

Following the guide here, I can successfully connect to a device, scan services and characteristics, and read/write/receive notifications without any issues. However, after disconnecting and re-connecting, I am often unable to either scan services/characteristics or unable to complete a read/write. I can't find anything in the logs to indicate why this is happening.

Once this happens I have to uninstall the application, disable Bluetooth, and restart the phone before it will start working again.

Whenever a device is disconnected I make sure to call close() on the BluetoothGatt object and set it to null. Any insights?


EDIT:
Log dumps: For these logs I rooted my phone and upped the trace levels of related items in /etc/bluetooth/bt_stack.conf

Successful connection - First attempt after rebooting the phone and installing the app. I am able to connect, discover all services/characteristics, and read/write.

Failed Attempt 1 - This is the next attempt after disconnecting from the successful connection above. It seems I was able to discover characteristics, but the first attempt to read returned a null value and disconnected soon thereafter.

Failed Attempt 2 - An example where I am not even able to discover services/characteristics.


EDIT 2:
The device to which I am trying to connect is based on TI's CC2541 chip. I obtained a TI SensorTag (also based on the CC2541) to play around with and discovered that TI released an android app for the SensorTag yesterday. However, this app has the same problem. I tested this on two other Nexus 4s with the same result: Connection to the SensorTag is successful the first or second time, but (according to the logs) fails to discover services thereafter, causing all sorts of crashes. I'm starting to wonder if it's an issue with this specific chip?

4

5 回答 5

189

重要的实施提示

(也许由于 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 以稳定蓝牙。

初学者教程

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

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

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

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

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

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

关闭 WIFI:

我也可以确认,关闭 WIFI 会使蓝牙 4.0 更加稳定,尤其是在 Google Nexus 上(我有一个 Nexus 7)。

问题

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

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

  • 连结 7
  • 摩托罗拉 Moto G

然而,开启 WIFI 的 BLE 扫描在以下情况下似乎相当稳定:

  • 三星S4
  • 宏达一

我的解决方法

我在短时间内扫描 BLE 3-4 秒,然后关闭扫描 3-4 秒。然后再次开启。

  • 显然,当我连接到 BLE 设备时,我总是关闭 BLE 扫描。
  • 当我与设备断开连接时,我重新启动 BLE(关闭然后打开适配器)以重置堆栈,然后再次开始扫描。
  • services当发现或characteristics失败时,我也会重置 BLE 。
  • 当我从应用程序应连接到的设备上获取广告数据时(比如说 500 次无法连接 - 这大约是 5-10 秒的广告),我再次重置 BLE。
于 2014-02-12T14:54:47.173 回答
10

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

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

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

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

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

于 2013-08-02T00:32:53.567 回答
8

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

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

btGatt.disconnect();
btGatt.close();
于 2016-02-13T19:07:23.683 回答
5

我面临着类似的问题。我的解决办法是

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

& 断开连接后关闭。

于 2019-04-05T14:38:08.200 回答