android学习笔记

android蓝牙BLE使用小结

2019-08-20  本文已影响0人  heheworld

最近产品新增一个小功能,具体需求是:
手机APP搜索连接蓝牙设备,向蓝牙设备写指令,蓝牙设备写指令回调,通知APP。
虽然功能简单,但实现时候也遇到一些小坑,整理下希望后来人少走弯路。

基础概念:

  1. 版本要求
    最低支持BLE的Android 系统是 4.3 Jelly Bean,也就是 API 18 才开始支持低功耗蓝牙,但只能作为中心设备去连接其他设备。
    从 Android 5.0 开始才支持外设模式。

  2. 传统蓝牙和低功耗蓝牙的区别
    BLE,全称为Bluetooth Low Energy,即蓝牙低功耗,较传统蓝牙最大的特点就是低功耗,多应用于对实时性要求较高,
    但对数据传输速率要求比较低的场景,比如血压计、键鼠等设备,而语音、音乐等对数据量传输比较大的场景依然需要使用传统蓝牙。
    参考
    蓝牙BLE介绍
    Android蓝牙开发—经典蓝牙和BLE(低功耗)蓝牙的区别

  1. 几个关键的类:
  1. 涉及到的权限
Manifest.permission.BLUETOOTH //允许应用去连接蓝牙设备
Manifest.permission.BLUETOOTH_ADMIN //允许应用找到与之连接的蓝牙设备
Manifest.permission.ACCESS_COARSE_LOCATION //android 6.0 后使用蓝牙需要该权限

遇到的问题

1.

搜索回调收不到
因为开启蓝牙搜索以及连接回调都是新起了一个线程,导致经常回调收不到,
自己测试了下,
A线程启动搜索连接,回调正常,结束操作。
B线程启动搜索连接,回调到A线程里面去。

后来stackflow上查了下,建议这些操作最好都放在主线程内。

相关问题,子线程开的定时器,延时发送,关闭的时候都会错乱。

2.

传输失败
因为BLE协议,每次写BluetoothGattCharacteristic只能20个字节。
所以要做分包传输,两次传输最好间隔500ms

3.

同一设备,多次连接后会提示连接失败。
操作处理完毕后,BluetoothGatt及时断开,最好先BluetoothGatt.disconnect();
然后在LeScanCallback里BluetoothGatt.close();
因为同一个主设备最多可以保证六个左右的连接。若多次连接没有及时断开,可能会引起这个问题。

4.

设备连接过慢

/**
* autoConnect 设置为false
* transport设置为BluetoothDevice.TRANSPORT_LE
**/
BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                     BluetoothGattCallback callback, int transport)

autoConnect 文档这么描述的
Whether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).

BluetoothDevice.TRANSPORT_LE 文档这么描述的
Prefer LE transport for GATT connections to remote dual-mode devices

/**
* status  参数表示 GATT通信的结果 GATT_SUCCESS 为成功 
* newState 连接状态,是BluetoothProfile.STATE_DISCONNECTED,BluetoothProfile.STATE_CONNECTED二者选一           
**/
BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                     BluetoothGattCallback callback, int transport)
其中 BluetoothGattCallback中   
public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) 
          
5.

BluetoothGattCallback中 onConnectionStateChange回调两个参数简述

/**
* status GATT通信的结果 GATT_SUCCESS 为成功 
* newState 连接状态,BluetoothProfile.STATE_DISCONNECTED,BluetoothProfile.STATE_CONNECTED二者选一    
**/
public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) 
6.
找不到BluetoothGattService的一个解决方案

通过反射清理之前连接的缓存。(讲是9.0屏蔽反射的渠道,但用三星S9+,和华为P20都正常使用)

    private boolean refreshDeviceCache(BluetoothGatt gatt) {
        try {
            BluetoothGatt localBluetoothGatt = gatt;
            Method localMethod = localBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
            if (localMethod != null) {
                boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt, new Object[0])).booleanValue();
                return bool;
            }
        } catch (Exception localException) {
        }
        return false;
    }
上一篇下一篇

猜你喜欢

热点阅读