蓝牙

安卓BLE,头发掉得快

2021-08-09  本文已影响0人  仕明同学

一年多了,没有来简书写文章,今天恰逢风高气爽,总结下个人对BLE蓝牙一些问题

image.png

什么是经典蓝牙,什么是BLE蓝牙,什么是双模蓝牙

image.png
A、经典蓝牙:

1)、传声音:如蓝牙耳机、蓝牙音箱。蓝牙设计的时候就是为了传声音的,所以是近距离的音频传输的不二选择。现在也有基于WIFI的音频传输方案,例如Airplay等,但是WIFI功耗比蓝牙大很多,设备无法做到便携。因此固定的音响有WIFI的,移动的如耳机、便携音箱清一色都是基于经典蓝牙协议的。

2)、传大量数据: 例如某些工控场景,使用Android或Linux主控,外挂蓝牙遥控设备的,可以使用经典蓝牙里的SPP协议,当作一个无线串口使用。速度比BLE传输快多了。

B、BLE蓝牙:

1)、耗电低,数据量小,如遥控类(鼠标、键盘),传感设备(心跳带、血压计、温度传感器、共享单车锁、智能锁、防丢器、室内定位)。

2)、目前手机和智能硬件通信的性价比最高的手段,直线距离约50米,一节5号电池能用一年,传输模组成本便宜,远比WIFI、4G等大数据量的通信协议更实用。虽然蓝牙距离近了点,但胜在直连手机,价格超便宜。以室内定位为例,商场每家门店挂个蓝牙beacon,就可以对手机做到精度10米级的室内定位,将来的蓝牙5.1更可以实现厘米级室内定位。

C、双模蓝牙:

1)、智能电视遥控器:很多智能电视配的遥控器带有语音识别,需要用经典蓝牙才能传输声音。而如果做复杂的按键,例如原本键盘表上没有的功能,经典蓝牙的HID按键协议就不行了,得用BLE做私有协议。

2)、降噪耳机:很多降噪耳机上通过APP来调节降噪效果,也是通过BLE来实现的私有通信协议。

开发过程中遇到的问题

1、已配对的列表消失问题

目前倾向于是系统做了一些操作

2、在扫描BLE设备的时候,有几率会发现由于BLE地扫描导致地整个App页面卡
3、进行BLE的基本操作导致BLE Crash问题
4、关于不断连接BLE的时候,底层报错status =133的问题
5、在蓝牙已经打开的状态下,开启蓝牙扫描的时候,getBluetoothLeScanner()==null,然后设备不能开启扫描
6、蓝牙的建立拦截的过程中,发生无响应的状态

开发中优化的建议

   /**
     * How to understand:
     * 1. A new task will be placed in corePool, the core thread pool, the size is 1, where corePoolSize=maximumPoolSize=1
     * 2. When the core thread pool is full, it will be placed on the LinkedBlockingQueue. If the LinkedBlockingQueue is a bounded queue, a bounded blocking queue composed of a linked list structure, and it is also full. size=Integer.MAX_VALUE
     * 3. Create a new task in the thread pool smaller than the maximum until the maximum thread pool is full
     * 4. It will go to the rejection queue to see what kind of rejection plan it is, and then just like that
     * 5. Because defaultHandler = new AbortPolicy(); it is possible to throw an exception, although this chance is small
     * 6. The execution time of the execute method is usually a slow process. If it is a fast process, you will not be placed in the thread pool, so I think this is suitable for download initialization
     */


/**
      * 如何理解:
      * 1.会在corePool,核心线程池中放置一个新任务,大小为1,其中corePoolSize=maximumPoolSize=1
      * 2.当核心线程池满时,会放到LinkedBlockingQueue上。 如果LinkedBlockingQueue是一个有界队列,一个由链表结构组成的有界阻塞队列,它也是满的。 大小=整数.MAX_VALUE
      * 3.在线程池中创建一个小于最大值的新任务,直到最大值线程池满
      * 4.它会去拒绝队列看它是什么拒绝计划,然后就这样
      * 5. 因为 defaultHandler = new AbortPolicy(); 有可能抛出异常,虽然这个机会很小
      * 6.execute方法的执行时间通常是一个缓慢的过程。 如果是快进程,你就不会被放到线程池中,所以我觉得这个适合下载初始化
      */
code

---- Updated Answer ----

I have found that its better to call bluetoothGatt.close() inside the onConnectionStateChanged callback. When you issue a disconnect it sends a message to the bluetooth device to request disconnect. Then once it responds you get the callback and close the bluetooth gatt connection. By waiting for the callback and not opening another gatt connection until its fully closed it seems to prevent multiple gatt objects from getting connected to the app.

其实就是需要在disconnect后,首先调用 GATT.colse()

Tip:

上一篇 下一篇

猜你喜欢

热点阅读