一、蓝牙4.0简介
蓝牙4.0包括传统蓝牙和低功耗蓝牙BLE两部分,其中BLE(Bluetooth Low Energy)是蓝牙4.0的核心,主打功能是快速搜索,快速连接,超低功耗保持连接和传输数据,弱点是数据传输速率低,由于BLE的低功耗特点,因此普遍用于穿戴设备。Android 4.3才开始支持BLE API,所以需要在蓝牙4.0和Android 4.3及其以上的系统上进行开发、运行。本项目利用一个Android系统pad和多个医疗设备进行通讯,pad作为客户端,医疗设备则为服务端。
二、BLE通信原理
BLE分为Service、Characteristic、Descriptor三部分,这三部分都由UUID作为唯一标示符。一个蓝牙4.0的终端可以包含多个Service,一个Service可以包含多个Characteristic,一个Characteristic包含一个Value和多个Descriptor,一个Descriptor包含一个Value。一般来说,Characteristic是pad与BLE终端设备交换数据的关键,Characteristic有较多的跟权限相关的字段。Android SDK提供了四个类帮助我们找到Characteristic:
1) BluetoothGatt:它是我们用的最多,也是最重要的一个类,为了便于理解,我们可以把它看成pad与BLE终端设备建立通信的一个管道,有了这个管道,才有了通信的前提。
2) BluetoothGattService:蓝牙设备的服务,在这里我们把它比喻成班级。而将Bluetoothdevice比喻成学校,一个学校里面可以有很多班级,也就是说每台BLE终端设备拥有多个服务,班级(各个服务)之间通过UUID(唯一标识符)区别。
3) BluetoothGattCharacteristic:蓝牙设备所拥有的特征,它就是我们所找的Characteristic,我们做的所有事情,目的就是为了得到它。在这里我们把它比喻成学生,一个班级里面有很多个学生,也就是说每个服务下拥有多个特征,学生(各个特征)之间通过UUID(唯一标识符)区别。
4) BluetoothGattDescriptor:对Characteristic的描述,例如范围、计量单位等。
简而言之,当我们想要用pad与BLE设备进行通信时,实际上也就相当于我们要去找一个学生交流,首先我们需要搭建一个管道,也就是我们需要先获取得到一个BluetoothGatt,其次我们需要知道这个学生在哪一个班级,学号是什么,这也就是我们所说的serviceUUID和charUUID,利用这两个信息可以找到他,也就是BluetoothGattCharacteristic。
这里还需要注意一下,BluetoothGattCharacteristic就像一个中介一样,在pad和BLE终端设备之间帮助这两者传递着信息,pad需要经过它发送数据,由它传递到BLE设备上,而BLE设备上的返回信息,也是先传递到它那边,然后pad再从它那边进行读取。
Android手机与BLE终端设备通信结果都是以回调的形式返回。
三、蓝牙4.0通信实现过程
- 扫描蓝牙BLE终端设备
调用startScan方法开始扫描,stopScan方法停止扫描,扫描到的设备都返回在回调函数mLeScanCallback里。
mBluetoothAdapter.startLeScan(mLeScanCallback);
mBluetoothAdapter.stopLeScan(mLeScanCallback);
其中mBluetoothAdapter表示蓝牙适配器,一个蓝牙设备只有一个mBluetoothAdapter。
- 连接蓝牙BLE终端设备
在打开蓝牙扫描到想连接的设备后,连接方法很简单,一句代码就可以实现(如下)。当开始连接BLE终端设备时,连接方法会自动返回一个BluetoothGatt对象,前面说过BluetoothGatt它相当于一个管道,是建立通信的前提。
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
其中,mGattCallback是一个回调方法,pad与BLE终端设备的通信结果将会通过它返回。
- 启动服务发现
连接成功后,我们就要去寻找我们所需要的服务,这里需要先启动服务发现。
mBluetoothGatt.discoverServices() ;
启动服务发现,它的结果也是通过回调函数onServicesDiscovered返回。
4.获取Characteristic
之前我们说过,我们的最终目的就是获取Characteristic来进行通信,正常情况下,我们可以从硬件工程师那边得到serviceUUID和characteristicUUID,也就是我们所比喻的班级号和学号,以此来获得我们的characteristic。(本项目还需要知道descriptorUUID,用于设置BluetoothGattDescriptor的通知属性,否则无法收到数据)
- 开始通信
我们在得到Characteristic后,就可以开始读写操作进行通信了。
a. 对于读操作来说,读取BLE终端设备返回的数据会通过回调方法mGattCallback中的onCharacteristicChanged函数返回。
b. 对于写操作来说,可以通过向Characteristic写入指令以此来达到控制BLE终端设备的目的:
Characteristic.setValue(b);
mBluetoothGatt.writeCharacteristic(Characteristic);
四、一对多设备连接
以上完成了蓝牙4.0一对一的通信,同理也可以实现一对多的蓝牙通信。
虽然BluetoothAdapter只能有一个,但BluetoothGatt可以有多个,将其放置与Arraylist容器中,逐一进行连接即可。
private ArrayList<BluetoothGatt> connectionQueue;
……
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false,mGattCallback);
connectionQueue.add(mBluetoothGatt);
补充:
Android 4.3版本只支持手机作central的角色,不能作为peripheral,因此无法让安卓蓝牙手机被BLE方式扫描到,只能扫描别的BLE设备。但是可以通过传统蓝牙(2.0)startDiscovery方式扫描到。
Android 5.0以后既可以当central,又可以当peripheral。即主从机角色都可以胜任。
此外,目前国内部分手机机型,必须通过第三方APP才能被扫描到,不支持直接被扫描。
网友评论