【HarmonyOS】鸿蒙应用低功耗蓝牙BLE的使用心得 (三)
一、前言
目前鸿蒙最新系统,经过测试还有两个BLE相关Bug正在修复:
1.获取本地设备蓝牙名称,会为空,只有点击到设置蓝牙中查看后,该接口才能获取到值
2.建立BLE链接后,断开链接,返回的状态没有已断开,只有断开中
鸿蒙相对于Android和IOS而言,对于蓝牙接口的划分其实非常友好,使用也很简单。不需要你套娃一样生成多个对象,蓝牙操作对象,例如GATT都是单例的形式,直接调用即可,例如:
dart
// 通过ble就可以直接操作低功耗蓝牙相关接口
this.gattClient = ble.createGattClientDevice(peerDevice);
try {
this.gattClient.connect();
} catch (err) {
console.error(TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
三、BLE低功耗蓝牙DEMO项目示例参考:
HaronyOS+BLE蓝牙DEMO
实现了BLE蓝牙完整的交互过程:
1.管理蓝牙的开启和关闭
2.外围设备的服务创建,广播等
3.中央设备的扫描,链接,读取特征和描述等
ScanResultPage .ets
dart
import { ArrayList, HashMap } from '@kit.ArkTS'
import { BleDeviceInfo } from '../bean/BleDeviceInfo'
import { promptAction } from '@kit.ArkUI';
import { EventHubUtils } from '../utils/EventHubUtils';
import { BLEMgr } from '../mgr/BLEMgr';
@Entry
@Component
struct ScanResultPage {
private mBLEMgr: BLEMgr = new BLEMgr();
private mCacheMap: HashMap<string, string> = new HashMap();
@State connStr: string = "";
@State optionSelect: number = -1;
aboutToAppear(): void {
EventHubUtils.getEventHub().on("ScanRes", this.onScanRes);
EventHubUtils.getEventHub().on("ConnStateChange", this.onConnStateChange);
}
aboutToDisappear(): void {
EventHubUtils.getEventHub().off("ScanRes", this.onScanRes);
EventHubUtils.getEventHub().off("ConnStateChange", this.onConnStateChange);
}
onConnStateChange = (state: string)=>{
if(state == "CONNECTING"){
this.connStr = "连接中";
}else if(state == "CONNECTED"){
this.connStr = "已连接";
// 进行设备的服务查询
this.mBLEMgr.discoverServices();
}else if(state == "DISCONNECTING"){
this.connStr = "断开中";
}else{
this.connStr = "断开连接";
setTimeout(()=>{
this.optionSelect = -1;
}, 2000);
}
}
onScanRes = (info: BleDeviceInfo)=>{
let deviceId: string = info.DeviceData?.deviceId ?? "";
if(!this.mCacheMap.hasKey(deviceId)){
this.mCacheMap.set(deviceId, deviceId);
this.mListDeviceInfo.push(info);
}
}
@State mListDeviceInfo: Array<BleDeviceInfo> = new Array();
@Builder ListView(){
List() {
ForEach(this.mListDeviceInfo, (item: BleDeviceInfo, index: number) => {
ListItem() {
Column(){
Text("设备ID: " + item.DeviceData?.deviceId).fontSize(px2fp(52)).fontColor(Color.White).width('100%')
Text("设备名: " + item.DeviceData?.deviceName).fontSize(px2fp(52)).fontColor(Color.White).width('100%')
Text("RSSI: " + item.DeviceData?.rssi).fontSize(px2fp(52)).fontColor(Color.White).width('100%')
Text(item.DeviceData?.connectable ? "连接状态: 可连接" : "连接状态: 不可连接").fontSize(px2fp(52)).fontColor(Color.White).width('100%')
if(this.optionSelect == index){
Row(){
Button(this.connStr).backgroundColor(Color.Yellow).fontColor(Color.Blue)
.onClick(()=>{
// 断开
AlertDialog.show({
title:"BLE断开",
message:"是否选择" + item.DeviceData?.deviceName + "进行BLE断开?",
autoCancel: true,
primaryButton: {
value:"确定",
action:()=>{
promptAction.showToast({ message: item.DeviceData?.deviceName + " 断开ing!"});
this.mBLEMgr.stopConnect();
}
},
secondaryButton: {
value:"取消",
action:()=>{
promptAction.showToast({ message: "取消!"});
}
},
cancel:()=>{
promptAction.showToast({ message: "取消!"});
}
});
})
if(this.connStr == "已连接"){
Button("读取特征值").backgroundColor(Color.Yellow).fontColor(Color.Blue)
.onClick(()=>{
this.mBLEMgr.getClient().readCharacteristicValue();
}).margin({ left: px2vp(10) })
Button("读取描述").backgroundColor(Color.Yellow).fontColor(Color.Blue)
.onClick(()=>{
this.mBLEMgr.getClient().readDescriptorValue();
}).margin({ left: px2vp(10) })
}
}
.width("100%")
}
Divider().height(px2vp(1)).width("100%")
}
.padding({
left: px2vp(35),
right: px2vp(35)
})
.width('100%')
.height(px2vp(450))
.justifyContent(FlexAlign.Start)
.onClick(()=>{
// 点击选择处理配对
AlertDialog.show({
title:"BLE连接",
message:"是否选择" + item.DeviceData?.deviceName + "进行BLE连接?",
autoCancel: true,
primaryButton: {
value:"确定",
action:()=>{
promptAction.showToast({ message: item.DeviceData?.deviceName + " 连接ing!"});
this.mBLEMgr.startConnect(item.DeviceData?.deviceId);
this.optionSelect = index;
}
},
secondaryButton: {
value:"取消",
action:()=>{
promptAction.showToast({ message: "取消!"});
}
},
cancel:()=>{
promptAction.showToast({ message: "取消!"});
}
});
})
}
}, (item: string, index: number) => JSON.stringify(item) + index)
}
.width('100%')
}
build() {
Column() {
this.ListView()
}
.height('100%')
.width('100%')
.backgroundColor(Color.Blue)
}
}