我目前正在开发一个使用蓝牙低功耗的应用程序(在 Nexus 4 上进行测试)。在开始使用 Android 4.3 中的官方 BLE API 后,我注意到在我第一次连接设备后,我很少能够再次成功连接/通信该设备或任何其他设备。
按照指南 here ,我可以成功连接到设备,扫描服务和特征,以及读/写/接收通知而没有任何问题。但是,断开连接并重新连接后,我经常无法扫描服务/特征或无法完成读/写。我在日志中找不到任何内容来说明为什么会发生这种情况。
一旦发生这种情况,我必须卸载应用程序、禁用蓝牙并重新启动手机,然后它才能再次开始工作。
每当设备断开连接时,我都会确保在 BluetoothGatt 对象上调用 close() 并将其设置为 null。有什么见解吗?
编辑:
日志转储:对于这些日志,我将手机 Root 并提高了/etc/bluetooth/bt_stack.conf 中相关项目的跟踪级别
Successful connection - 重新启动手机并安装应用程序后的第一次尝试。我能够连接、发现所有服务/特征以及读/写。
Failed Attempt 1 - 这是从上述成功连接断开后的下一次尝试。似乎我能够发现特征,但第一次尝试读取返回一个空值并在此后不久断开连接。
Failed Attempt 2 - 我什至无法发现服务/特征的示例。
编辑 2:
我尝试连接的设备基于 TI 的 CC2541 芯片。我获得了 TI SensorTag (也是基于CC2541)玩弄发现TI发布了an android app昨天的 SensorTag。但是,这个应用有同样的问题。我在另外两台 Nexus 4 上测试了这个,结果相同:第一次或第二次连接到 SensorTag 成功,但(根据日志)失败之后发现服务,导致各种崩溃。我开始怀疑这是不是这个特定芯片的问题?
最佳答案
重要的实现提示
(也许由于 Android 操作系统更新,其中一些提示不再需要。)
- 一些设备,如 Nexus 4 和 Android 4.3 take 45+ seconds to connect using an existing gatt instance .解决方法:始终在断开连接时关闭 gatt 实例,并在每次连接时创建一个新的 gatt 实例。
- 别忘了调用
android.bluetooth.BluetoothGatt#close()
- 在里面开始一个新线程
onLeScan(..)
然后连接。原因:BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)
如果在LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[ ] scanRecord)
使用 Android 4.3 在三星 Galaxy S3 上的同一线程中(至少对于构建 JSS15J.I9300XXUGMK6) - Most devices filter advertising
- 最好不要使用
android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback)
带有过滤某些服务UUID的参数 因为这在带有 Android 4.3 和 doesn't work for 128bit UUIDs 的三星 Galaxy S3 中完全被打破了。一般。 - Gatt 每次只能处理一个命令。如果几个命令一个接一个地被调用,第一个被取消 due to the synchronous nature of the gatt implementation.
- 即使在装有 Android 5 的现代设备上,我也经常看到 Wifi 会干扰蓝牙,反之亦然。 万不得已,请关闭 wifi 以稳定蓝牙。
初学者教程
对于新手来说,一个相当不错的切入点可能是这个视频教程:为 Android 开发蓝牙智能应用程序 http://youtu.be/x1y4tEHDwk0
下面描述的问题和解决方法现在可能已通过操作系统更新修复
解决方法:我可以“稳定”我的应用这样做...
- 我为用户提供了“重启蓝牙”设置。如果启用了该设置,我会在某些点重新启动蓝牙,这表明 BLE 堆栈的开始变得不稳定。例如。如果 startScan 返回 false。如果 serviceDiscovery 失败,也可能是一个好点。我只是关闭并打开蓝牙。
- 我提供了另一个设置“关闭 WiFi”。如果启用了该设置,我的应用会在应用运行时关闭 Wifi(然后再将其重新打开)
这项工作是基于以下经验...
- 在大多数情况下,重启蓝牙有助于解决 BLE 问题
- 如果您关闭 Wifi,BLE 堆栈会变得更加稳定。但是,它在大多数打开 wifi 的设备上也能正常工作。
- 如果您关闭 Wifi,在大多数情况下,重新启动蓝牙会完全恢复 BLE 堆栈,而无需重新启动设备。
关于Android 4.3 低功耗蓝牙不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17870189/