Android蓝牙开发的各种坑

一、对蓝牙设备的操作不能并行,只能串行,即每次都要在收到上一个操作的回调后才能继续下一个操作。但是断开连接例外,断开连接要马上closeGatt,不用等任务队列中的其他操作了。而且要给所有正在执行或者准备执行的任务都cancel。

二、有时候蓝牙协议栈出现异常可能收不到回调,所以我们要对每个操作做超时检查,否则后面的所有操作都被阻塞了。

三、对于超时的任务,最好closeGatt,下次重新连接的时候重开一个gatt。

四、蓝牙连接可能不稳定,最好支持失败自动重试机制,尤其是连接和发现服务,因为80%的问题都发生在建立连接和发现服务的时候,而且这一块也是最耗时的。

五、同一个设备的所有操作最好都放在同一个线程串行执行,最好不要放在UI线程,虽然这些操作都是异步的,理论上来说不会耗时,但是由于涉及到跨进程,还是有可能出现ANR。另外不建议每个设备都开一个线程,设备多了会费内存也会降低性能。较好的做法是开一个线程,所有设备的操作都在该线程中发起,虽然占用同一个线程,但是每个设备各自维护自己的任务队列。

六、设备的gatt在不用时要及时关闭,系统支持的连接句柄数是有限的,当达到上限后无法再建立新的连接了。

七、当连接断开后要调closeGatt释放资源,不用调disconnect,也不要下次复用之前的gatt来reconnect,因为有的手机上重连可能会存在问题,比如重连后死活发现不了service。这种情况下,最好只要断开连接就close gatt,下次连接时打开全新的gatt,这样就可以发现service了。

八、BLE的特征一次读写最大长度20字节。

九. Android手机会对连接过的BLE设备的Services进行缓存,若设备升级后Services等有改动,则程序会出现通讯失败。此时就得刷新缓存,反射调用BluetoothGatt类总的refresh()方法。

十、connectGatt() 在某些三星手机上只能在UI线程调用。

十一、Android L 新API扫描设备换为 startScan(List, ScanSettings, ScanCallback)。

十二、 Android M 必须拥有定位权限才能扫描BLE设备。

十三、一个主设备(例如Android手机)可以同时连接多个从设备(一般为6个,例如智能硬件。超过就连接不上了),一个从设备只能被一个主设备连接,一旦从设备连接上主设备,就停止广播,断开连接则继续广播。在任何时刻都只能最多一个设备在尝试建立连接。如果同时对多个蓝牙设备发起建立Gatt连接请求。如果前面的设备连接失败了,则后面的设备请求会被永远阻塞住,不会有任何连接回调。所以建议:如果要对多个设备发起连接请求,最好是一个接一个的顺序同步请求管理。

十四、任何出错,超时,用完就马上调用Gatt.disconnect(), Gatt.close()。

十五、从bindService 到 onServiceConnected 这个回调花费时间较长, onServiceConnected 这个回调很可能在 MainActivity onResume之后才执行, 所以不要指望onResume里去执行扫描,因为此时serviceConnected 回调都尚未执行

十六、getBtAdapter().enable()是异步,立即返回,但从 off 到 on 的过程需要一个时间所以只能监听系统broadcast发出的intent里的state

十七、 多次扫描蓝牙,在华为荣耀,魅族M3 NOTE 中有的机型,会发现多次断开–扫描–断开–扫描… 会扫描不到设备,此时需要在断开连接后,不能立即扫描,而是要先停止扫描后,过2秒再扫描才能扫描到设备。

十八、扫描尽量不要放在主线程进行,可以放入子线程里。不然有些机型会出现 do too many work in main thread.

你可能感兴趣的:(Android-基础)