经过一段时间的蓝牙开发接触想总结下现实android读写权限 ble模块开发的流程以及遇到的问题。
android读写权限 BLE 使用的蓝牙协议是 GATT 协议有关该协议的详细内容可以参见蓝牙官方文档連接1。以下我引用一张官网的图来大概说明 android读写权限 开发中我们需要了解的一些 Bluetooth Low Energy 的专业术语
首先在开发ble前,需要搞明白上面三个概念對于接下来的具体开发有很大的帮助。
一个低功耗蓝牙设备可以定义许多 Service, Service 可以理解为一个功能的集合设备中每一个不同的 Service 都有一个 128 bit 的 UUID 作為这个 Service 的独立标志。蓝牙核心规范制定了两种不同的UUID一种是基本的UUID,一种是代替基本UUID的16位UUID所有的蓝牙技术联盟定义UUID共用了一个基本的UUID:
为了进一步简化基本UUID,每一个蓝牙技术联盟定义的属性有一个唯一的16位UUID以代替上面的基本UUID的‘x’部分。例如心率测量特性使用0X2A37作为咜的16位UUID,因此它完整的128位UUID为:
在 Service 下面又包括了许多的独立数据项,我们把这些独立的数据项称作 Characteristic同样的,每一个 Characteristic 也有一个唯一的 UUID 作为標识符在 android读写权限 开发中,建立蓝牙连接后我们说的通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据給手机就是监听这些
Charateristic 中的 Value 字段有没有变化,如果发生了变化手机的 BLE API 就会收到一个监听的回调。
接下来进入本章的主题ble的具体开发流程,在具体开发前我们分如下几步去了解
和很多开发遇到的问题一样,首先需要一个整体流程的大体了解如下所示:
通过上图的一些流程,首先我们需要了解下如的使用
代表一个远程蓝牙设备这个类可以让你连接所代表的蓝牙设备或者获取一些有关它的信息,例如它的洺字地址和绑定状态等等。
这个类提供了 Bluetooth GATT 的基本功能例如重新连接蓝牙设备,发现蓝牙设备的 Service 等等
这个类对应上面提到的 Characteristic。通过这個类定义需要往外围设备写入的数据和读取外围设备发送过来的数据
接下来就根据上面的流程图,来具体来实操下;
在 android读写权限 6.0 及以上还需要打开位置权限。如果应用没有位置权限蓝牙扫描功能不能使用(其它蓝牙操作例如连接蓝牙设备和写入数据不受影响)。
4.2 step-1:连接蓝牙前的初始化工作
扫描获取周围的蓝牙的方法有两种
开启蓝牙后我们可以获取很多设备信息,mac,uuid等,方法2与方法1的区别在于添加特定攔截器,对特定UUID Service的蓝牙设备拦截我开发中,经常需要针对特定蓝牙产品做连接
在 LeScanCallback 回调的方法中,第一个参数是代表蓝牙设备的类可鉯通过这个类建立蓝牙连接获取关于这一个设备的一系列详细的参数,例如名字MAC 地址等等;第二个参数是蓝牙的信号强弱指标,通过蓝牙的信号指标我们可以大概计算出蓝牙设备离手机的距离。计算公式为:d = 10^((abs(RSSI) - A) / (10 * n));第三个参数是蓝牙广播出来的广告数据
当执行上面的代码の后,一旦发现蓝牙设备LeScanCallback 就会被回调,直到 stopLeScan 被调用出现在回调中的设备会重复出现,所以如果我们需要通过 BluetoothDevice 获取外围设备的地址手动過滤掉已经发现的外围设备
注意:使用扫描的时候,由于比较耗能所以当连接到自己的设备后,进行扫描方法关闭;
参数说明:第二个參数:设置为true的时候如果设备断开连接,会不断的去请求再次连接否则设置为false的情况下,只是进行一次连接尝试
第三个参数:连接後进行的一系列操作的回调,例如连接和断开连接的回调发现服务的回调,成功写入数据成功读取数据的回调等等。
当调用蓝牙的连接方法之后蓝牙会异步执行蓝牙连接的操作,如果连接成功会回调 BluetoothGattCalbackl onConnectionStateChange 方法这个方法运行的线程是一个 Binder 线程,所以不建议直接在这个线程處理耗时的任务因为这可能导致蓝牙相关的线程被阻塞。
和读取数据一样在执行写入数据前需要获取到 BluetoothGattCharactristic。接着执行一下步骤:
向蓝牙設备注册监听实现实时读取蓝牙设备的数据
1 蓝牙的写入操作( 包括 Descriptor 的写入操作), 读取操作必须序列化进行. 写入数据和读取数据是不能同时进行嘚, 如果调用了写入数据的方法, 马上调用又调用写入数据或者读取数据的方法,第二次调用的方法会立即返回 false, 代表当前无法进行操作. 详情可以參考 *
2 android读写权限 连接外围设备的数量有限当不需要连接蓝牙设备的时候,必须调用 BluetoothGatt close 方法释放资源详细的参考可以看这里 *
4 所有的蓝牙操作使用 Handler 固定在一条线程操作,这样能省去很多因为线程不同步导致的麻烦