Android 4.3蓝牙低功耗不稳定
我目前正在开发一个应用程序,将使用蓝牙低功耗(Nexus 4testing)。 在开始使用Android 4.3中的官方BLE API后,我注意到在我第一次连接设备后,我很less能够成功连接到该设备或任何其他设备。
按照这里的指导,我可以成功地连接到设备,扫描服务和特性,并且读/写/接收通知没有任何问题。 但是,在断开和重新连接之后,我经常无法扫描服务/特性或者无法完成读/写。 我无法在日志中find任何内容来指出发生这种情况的原因。
一旦发生这种情况,我必须卸载应用程序,禁用蓝牙,并重新启动手机,才能重新开始工作。
每当一个设备断开连接时,我确保在BluetoothGatt对象上调用close()并将其设置为null。 任何见解?
编辑:
日志转储:对于这些日志,我植根了我的手机,并在/etc/bluetooth/bt_stack.conf中增加了相关项目的跟踪级别
成功连接 – 重新启动手机并安装应用程序后首次尝试。 我能够连接,发现所有的服务/特性,以及读/写。
尝试失败1 – 这是从上面的成功连接断开后的下一次尝试。 看来我能够发现特征,但第一次尝试读取返回一个空值,然后很快就断开连接。
尝试失败2 – 一个例子,我甚至无法发现服务/特性。
编辑2:
我尝试连接的设备基于TI的CC2541芯片。 我获得了TI SensorTag (也是基于CC2541),并发现TI昨天为SensorTag发布了一款Android应用 。 但是,这个应用程序也有同样的问题。 我在另外两台Nexus 4上testing了这个结果:第一次或第二次连接SensorTag成功,但是(根据日志)之后没有发现服务,造成各种崩溃。 我开始怀疑这个芯片是否有问题?
重要的实施提示
(也许由于Android操作系统更新,其中一些提示不再需要了。)
- 像Nexus 4和Android 4.3的一些设备需要45+秒才能使用现有的gatt实例进行连接 。 解决方法:始终closures断开连接的gatt实例,并在每个连接上创build一个新的gatt实例。
- 不要忘记调用
android.bluetooth.BluetoothGatt#close()
- 在
onLeScan(..)
内启动一个新的线程 ,然后连接。 原因:在Samsung Galaxy上的同一线程中,如果在LeScanCallback() {...}.onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
中调用BluetoothDevice#connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)
S3与Android 4.3(至less用于构buildJSS15J.I9300XXUGMK6) - 大多数设备过滤广告
- 最好不要使用
android.bluetooth.BluetoothAdapter#startLeScan(UUID[] serviceUuids, LeScanCallback callback)
来过滤某些服务UUID,因为这在Samsung Galaxy S3中完全被Android 4.3破解,并且不适用于128位UUID 。 - 加特总是可以一次处理一个命令 。 如果几个命令被连续调用,第一个命令由于gatt实现的同步性质而被取消。
- 我甚至经常在Android 5的现代设备上看到,Wifi会干扰蓝牙,反之亦然。 作为最后的手段,关掉wifi来稳定蓝牙。
初学者教程
对于新手来说,一个相当不错的入门点就是这个video教程:为Android开发蓝牙智能应用http://youtu.be/x1y4tEHDwk0
下面介绍的问题和解决方法现在可能已经由操作系统更新解决了
解决办法:我可以“稳定”我的应用程序,做到这一点…
- 我向用户提供“重新启动蓝牙”设置。 如果启用该设置,则在某些指示BLE堆栈开始变得不稳定的点上重新启动蓝牙。 例如,如果startScan返回false。 serviceDiscovery失败也可能是一个好的方面。 我只是closures和打开蓝牙。
- 我提供了另一个设置“WiFi转向”。 如果启用了该设置,那么当应用程序正在运行时,我的应用程序将closuresWifi(之后将其重新打开)
这个解决方法是基于以下经验…
- 在大多数情况下,重新启动蓝牙有助于解决BLE问题
- 如果您closuresWifi,BLE堆栈变得更加稳定。 但是,它也适用于打开wifi的大多数设备。
- 如果closuresWifi,则在大多数情况下,重新启动蓝牙可以完全恢复BLE堆叠,而无需重新启动设备。
closuresWIFI:
我也可以确认,closuresWIFI使蓝牙4.0更稳定,特别是在谷歌Nexus(我有一个Nexus 7)。
问题
是我正在开发的应用程序需要 WIFI和连续的蓝牙LE扫描 。 所以把WIFI关掉是我的select。
而且我已经意识到, 持续的蓝牙LE扫描实际上可以终止WIFI连接 ,并使WIFI适配器无法重新连接到任何WIFInetworking,直到BLE扫描为ON。 (我不确定移动networking和移动互联网)。
这肯定发生在以下设备上:
- Nexus 7
- 摩托罗拉Moto G
不过,使用WIFI进行BLE扫描似乎相当稳定:
- 三星S4
- HTC One
我的解决方法
我短时间扫描BLE 3-4秒,然后closures扫描3-4秒 。 然后再打开。
- 当我连接到BLE设备时,显然我总是closuresBLE扫描。
- 当我从设备上断开连接后,重新开始扫描之前,重新启动BLE(将适配器closures,然后再打开)以重置堆栈。
- 当发现
services
或characteristics
失败时,我也重置BLE。 - 当我从一个应用程序应该连接到的设备(可以说500次,而无法连接 – 这大约5-10秒的广告)获得广告数据时,我重新设置了BLE。
确保您的Nexus与设备配对。 我无法validation通讯是否正常工作,但是您将可以在不重新启动的情况下连接多次。 看起来第一个连接不需要配对,但所有后续的尝试都是这样做的。
我会在几天内更新这个答案,当我testing服务发现和gatt读取和写入请求而不重新启动。
编辑:事实certificate,我正在testing开发固件版本(我们的传感器),如果不配对,造成的问题。 我们最新的生产固件版本在2540和2541上运行良好。
编辑:我没有注意到,在Nexus 7 2013,WiFiclosures时连接更稳定。 我想知道这是否有助于其他人。
编辑:我似乎有配对倒退。 一切工作正常,当不配对。 配对后,我正在经历与OP完全相同的症状。 这只是不知道,如果这是关系到我们的固件或Android BLE API。 如果testing这个,请小心,因为一旦配对,您可能无法解除由于在这篇文章 3b解释的错误。
在某些模型中存在缺陷: https : //code.google.com/p/android/issues/detail?id=180440
另一方面在我的情况下,问题是,我的连接没有正确closuresonDestroy方法。 正确closures后,问题不存在,无论是打开或closures无线networking。
btGatt.disconnect(); btGatt.close();