前段时间,项目要接入一个ble硬件,以前也没接触过ble开发,在查阅不少资料和踩了不少坑才完成任务,因此打算写一个简单的ble开发步骤,希望能帮助到初次接触ble开发的同学。
BLE相关术语简介
GATT:GATT 的全名是 Generic Attribute Profile(姑且翻译成:普通属性协议),它定义两个 BLE 设备通过叫做 Service 和 Characteristic 的东西进行通信。
Profile:Profile 并不是实际存在于 BLE 外设上的,它只是一个被 Bluetooth SIG 或者外设设计者预先定义的 Service 的集合。
Service:Service 是把数据分成一个个的独立逻辑项,它包含一个或者多个 Characteristic。每个 Service 有一个 UUID 唯一标识。 UUID 有 16 bit 的,或者 128 bit 的。16 bit 的 UUID 是官方通过认证的,需要花钱购买,128 bit 是自定义的,这个就可以自己随便设置。
Characteristic:在 GATT 事务中的最低界别的是 Characteristic,Characteristic 是最小的逻辑数据单元,与 Service 类似,每个 Characteristic 用 16 bit 或者 128 bit 的 UUID 唯一标识。在 Android 开发中,建立蓝牙连接后,通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据给手机就是监听这些 Charateristic 中的 Value 字段有没有变化,如果发生了变化,手机的 BLE API 就会收到一个监听的回调。
下面是一张来自官网的结构图
更多关于BLE GATT介绍可查看以下链接
BLE GATT介绍
GATT PROFILE 介绍
Android BLE开发相关API介绍
BluetoothAdapter
BluetoothAdapter 拥有基本的蓝牙操作,例如开启蓝牙扫描,使用已知的 MAC 地址 (BluetoothAdapter#getRemoteDevice)实例化一个 BluetoothDevice 用于连接蓝牙设备的操作等等。
BluetoothDevice
代表一个远程蓝牙设备。这个类可以连接所代表的蓝牙设备或者获取一些有关它的信息,例如它的名字,地址和绑定状态等等。
BluetoothGatt
这个类提供了 Bluetooth GATT 的基本功能。例如重新连接蓝牙设备,发现蓝牙设备的 Service 、读写ble设备等等。
BluetoothGattService
对应前文所介绍的Service,通过 BluetoothGatt.getService 获得,通过这个类的 getCharacteristic(UUID uuid) 进一步获取 Characteristic 实现蓝牙数据的双向传输。
BluetoothGattCharacteristic
对应前文提到的 Characteristic。对ble设备的读写主要通过这个类来完成,也是我们主要打交道的类。
BLE设备接入开发
权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
连接设备
//先去获取BluetoothAdapter
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//检查手机蓝牙开关、是否支持ble
private void checkBluetooth() {
//是否支持蓝牙功能
if (mBluetoothAdapter == null) {
return;
}
//是否支持BLE
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(mContext, "不支持BLE功能", Toast.LENGTH_SHORT).show();
return;
}
//是否打开蓝牙开关
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(mContext, "请打开蓝牙开关", Toast.LENGTH_SHORT).show();
return;
}
//搜索设备
scanBleDevice(true);
}
/**
* 搜索ble设备
* @param enable 开始搜索或停止搜索
*/
private void scanBleDevice(final boolean enable) {
if (enable) {
//开始搜索设备,搜索到设备会执行回调接口mLeScanCallback
mBluetoothAdapter.startLeScan(mLeScanCallback);
isScanning = true;
//搜索设备十分耗电,应该避免长时间搜索,这里设置10s超时停止搜索
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
scanBleDevice(false);
Toast.makeText(mContext, "搜索超时,请重试", Toast.LENGTH_SHORT).show();
}
}, 10 * 1000);
} else {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
isScanning = false;
}
}
/**
* 设备搜索回调
*/
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device,