OpenHarmony BLE蓝牙连接

系统 OpenHarmony
这里将介绍如何通过OpenHarmony提供的@ohos.bluetooth (蓝牙接口)打开当前设备的蓝牙,关闭蓝牙,以及连接BLE蓝牙设备。

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

OpenHarmony BLE蓝牙设备连接

1、简介

OpenHarmony蓝牙模块提供了基础的传统蓝牙能力以及BLE的扫描、广播等功能,这里将介绍如何通过OpenHarmony提供的@ohos.bluetooth (蓝牙接口)打开当前设备的蓝牙,关闭蓝牙,以及连接BLE蓝牙设备。

2、设备与环境

  • 设备:九联s905l3a机顶盒、开鸿智谷学生卡BLE蓝牙设备
  • 系统:OpenHarmony 3.2 beta2
  • SDK:9

演示视频:​OpenHarmony BLE蓝牙设备连接​

3、逻辑流程

OpenHarmony BLE蓝牙连接-开源基础软件社区

首先机顶盒在开始的时候获取蓝牙相关权限,然后通过OpenHarmony提供的蓝牙接口打开蓝牙,接着订阅发现BLE设备发现事件,然后通过OpenHarmony提供的蓝牙接口开启BLE设备扫描,当发现到了BLE蓝牙设备后,进行上报,BLE设备发现事件触发,获取到来自BLE设备的广播信息包,然后进行BLE蓝牙连接。

4、实现过程

(1)获取蓝牙相关权限

在使用蓝牙接口之前,首先要让设备获取一下权限:

  • ohos.permission.USE_BLUETOOTH // 允许应用查看蓝牙的配置。
  • ohos.permission.DISCOVER_BLUETOOTH // 允许应用配置本地蓝牙,查找远端设备且与之配对连接。
  • ohos.permission.LOCATION // 允许应用获取设备位置信息。
  • ohos.permission.MANAGE_BLUETOOTH // 允许应用配对蓝牙设备,并对设备的电话簿或消息进行访问。

打开DevEco Studio 3.1.0.200,创建新的Stage项目,在项目中的module.json文件中添加相关权限:

"requestPermissions": [
{
"name": "ohos.permission.USE_BLUETOOTH",
"reason": "$string:grant_use_bluetooth",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.DISCOVER_BLUETOOTH",
"reason": "$string:grant_discovery_bluetooth",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.LOCATION",
"reason": "$string:grant_location",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
}
},
{
"name": "ohos.permission.MANAGE_BLUETOOTH",
"reason": "$string:grant_manage_bluetooth",
"usedScene": {
"abilities": [
"MainAbility"
],
"when": "inuse"
}
}
]

(2)打开设备的蓝牙

首先,通过调用 bluetooth.getState() 蓝牙接口来获取当前设备蓝牙是否打开,并设置蓝牙开关的标识位 isOn。

async aboutToAppear() {
// 等待获取蓝牙权限
await globalThis.abilityContext.requestPermissionsFromUser(['ohos.permission.USE_BLUETOOTH', 'ohos.permission.DISCOVER_BLUETOOTH', 'ohos.permission.LOCATION', 'ohos.permission.MANAGE_BLUETOOTH'])
logger.info(TAG, `获取权限 grantPermission,requestPermissionsFromUser,PermissionRequestResult`)
// 获取蓝牙状态
let state = bluetooth.getState()
// 判断当前设备蓝牙是否打开
if (state === bluetooth.BluetoothState.STATE_ON) {
this.isOn = true
}
if (state === bluetooth.BluetoothState.STATE_OFF) {
this.isOn = false
}
}

如果当前设备蓝牙未打开,则通过调用 bluetooth.enableBluetooth() 蓝牙接口来打开蓝牙。

// 打开蓝牙函数
initBluetooth() {
this.enable = bluetooth.enableBluetooth()
// 判断蓝牙是否成功打开
if(this.enable==true){
prompt.showToast({
message: 'Open bluetooth ' + this.enable,
duration: 2000,
});
}
}

(3)注册发现BLE设备监听器

在设备打开蓝牙之后,通过调用 bluetooth.BLE.on('BLEDeviceFind') 蓝牙接口来订阅BLE设备发现上报事件。该接口参数如下:

OpenHarmony BLE蓝牙连接-开源基础软件社区

通过注册发现BLE设备监听器,可以得到发现设备的集合,BLE设备的广播包、地址、信号强度rssi,在这里发现获取连接BLE设备名字的接口 getDeviceName 无法成功调用,所以自己通过解析广播包来获取设备名字。

// 订阅BLE设备发现上报事件
// 获取到的data包括BLE设备的广播包、地址、信号强度rssi
bluetooth.BLE.on('BLEDeviceFind', (data) => {
logger.info(TAG, `enter on bluetoothBLEDeviceFind`)
logger.info("rgytl 开始扫描设备地址! 1")
if (data !== null && data.length > 0) {
logger.info("rgytl 开始扫描设备地址! 2")
if (this.discoveryBleList.indexOf(data[0]) === -1) {
// 把发现的设备地址存入列表
this.discoveryBleList.push(data[0].deviceId)
logger.info("rgytl ---- discoveryBleList = "+JSON.stringify(this.discoveryBleList))
// 读取广播包,解析广播包,得到设备名字,并存入设备列表
var i = 0;
var x = data[0].data[i]
var y = data[0].data[i + 1]
while(y!=0x09 && i+x+2<data[0].data.byteLength){
i = i+x+1
x = data[0].data[i]
y = data[0].data[i+1]
}

let arr = data[0].data.slice(i+2,i+x+1)

var BLEName = ""
for(let j=0;j<arr.byteLength;j++){
BLEName+=String.fromCharCode(arr[j])
}
logger.info("rgytl ---- discoveryBleList = "+BLEName)
// 把通过广播包解析的BLE设备名字存入设备名字列表
this.BleInfo.push(BLEName)
// 把发现的BLE设备信号存入设备信号强度列表
this.BleRssi.push(data[0].rssi)
logger.info("rgytl ---- discoveryBleList = "+data[0].rssi)
}
logger.info(TAG, `开启扫描 discoveryBleList = ${JSON.stringify(this.discoveryBleList)}`)
}
})

(4)开启BLE设备扫描

在完成订阅BLE设备发现上报事件后,通过调用 bluetooth.BLE.startBLEScan 接口去开启BLE设备扫描,通过该接口,可以对扫描BLE设备进行过滤,可以过滤的参数有:BLE设备的地址、名字、以及服务的UUID等。

OpenHarmony BLE蓝牙连接-开源基础软件社区

在这里,我设置只扫描包含我BLE设备名字的BLE设备,这样子就不会说扫描到一大堆其他的BLE设备,影响使用,只需要开启一次扫描和订阅一次BLE设备发现上报事件就可以了,使用的时候只要没有关闭,就不需要重复调用。

// 设置蓝牙BLE扫描模式(根据名字扫描)
bluetooth.BLE.startBLEScan(
[{
deviceId: null,
name: "ble slave test",
serviceUuid: null
}],
{
interval: 0,
dutyMode: bluetooth.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: bluetooth.MatchMode.MATCH_MODE_AGGRESSIVE,
}
)

(5)连接BLE设备

在扫描到BLE设备之后,可以通过 on(‘BLEConnectionStateChange’) 来订阅获取BLE设备的连接状态变化事件,在使用该接口之前,要先通过 bluetooth.BLE.createGattClientDevice('XX:XX:XX:XX:XX:XX') 接口创建一个可使用的GattClientDevice实例。

OpenHarmony BLE蓝牙连接-开源基础软件社区

// 订阅BEL状态变化
if(this.BleOnflag){
// 只创建一个GattClient对象
this.BleOnflag = false
this.BLEDevice = bluetooth.BLE.createGattClientDevice(item);
// 订阅获取BLE设备的连接状态变化事件
this.BLEDevice.on('BLEConnectionStateChange', (data) => {
console.log('bluetooth connectState state changed');
let connectState = data.state;
// 根据不通的连接状态,提示不同的信息
if(JSON.stringify(connectState) == 0){
logger.info(`connectState = ${JSON.stringify(connectState)},断开连接`)
prompt.showToast({
message: '断开连接',
duration: 2000,
});
} else if(JSON.stringify(connectState) == 2){
logger.info(`connectState = ${JSON.stringify(connectState)},连接成功`)
prompt.showToast({
message: '连接成功',
duration: 2000,
});
} else if(JSON.stringify(connectState) == 1){
logger.info(`connectState = ${JSON.stringify(connectState)},正在连接`)
} else {
logger.info(`connectState = ${JSON.stringify(connectState)},正在断连`)
}
logger.info(`connectState = ${JSON.stringify(connectState)}`);
})
}

在前面通过 bluetooth.BLE.createGattClientDevice(item) 创建一个GattClientDevice实例 BLEDevice 后,我们可以通过该实例去调用 connect() 方法连接BLE设备。注意,GattClientDevice实例 只需要创建一个就可以。

OpenHarmony BLE蓝牙连接-开源基础软件社区

// 连接蓝牙
let BLEConnect = this.BLEDevice.connect()
// 如果连接成功,则把BLE设备存入连接成功列表
if(BLEConnect){
this.deviceBleList.push(item)
}

(6)结尾处理

当不连接BLE设备的时候,要记得关闭BLE设备扫描,取消订阅设备发现事件。

取消BLE设备连接,通过之前创建的GattClientDevice实例 BLEDevice 调用 disconnect() 方法断开连接BLE设备。

Button("断开")
.alignSelf(ItemAlign.Center)
.onClick(() => {
AlertDialog.show({
title: $r('app.string.disconnect'),
message: '此操作将会断开该设备的连接',
primaryButton: {
value: $r('app.string.cancel'),
action: () => {
}
},
secondaryButton: {
value: $r('app.string.confirm'),
action: () => {
// 断开连接BLE设备
let BLEdisConnect = this.BLEDevice.disconnect()
if(BLEdisConnect){
logger.info(`connectState BLEdisConnect = ${JSON.stringify(BLEdisConnect)},断开连接`)
// 移出BLE设备连接列表
this.deviceBleList.pop(item)
}
}
}
})
})

在断开连接、关闭蓝牙之后,可以通过 off(‘connectStateChange’) 取消订阅BLE连接状态变化事件、bluetooth.BLE.stopBLEScan 停止BLE扫描、以及 bluetooth.BLE.off(‘BLEDeviceFind’) 取消订阅BLE设备发现上报事件,最后通过 bluetooth.disableBluetooth() 关闭蓝牙。

.onChange((isOn: boolean) => {
if (isOn) {
this.isOn = true
this.initBluetooth()
} else {
this.isOn = false
bluetooth.BLE.off('BLEDeviceFind',()=>{
logger.info("rgytl 取消BLE设备发现订阅!")
})
bluetooth.BLE.stopBLEScan()
this.disable = bluetooth.disableBluetooth()
this.discoveryList = []
this.BleInfo = []
this.BleRssi = []
if(this.disable==true){
prompt.showToast({
message: 'Close bluetooth ' + this.disable,
duration: 2000,
});
}
}
})
5、参考文档

​OpenAtom OpenHarmony 蓝牙​

​应用权限列表​

​OpenHarmony Gitee 蓝牙​

文章相关附件可以点击下面的原文链接前往下载

 ​​https://ost.51cto.com/resource/2700​

想了解更多关于开源的内容,请访问:

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

责任编辑:jianghua 来源: 51CTO 开源基础软件社区
相关推荐

2022-11-17 15:26:06

低功耗蓝牙鸿蒙

2023-03-08 21:30:33

2015-09-22 11:04:24

蓝牙4.0开发

2022-01-25 16:54:14

BLE操作系统鸿蒙

2022-07-07 14:32:30

蓝牙技术鸿蒙

2021-10-30 07:55:00

BLE 蓝牙开发

2015-02-27 16:03:26

Android源码Bluetooth_4BLE蓝牙通信

2023-09-19 15:58:13

Zigbee蓝牙

2022-06-07 10:40:05

蓝牙鸿蒙

2023-10-08 15:19:40

2010-01-08 15:35:30

Ubuntu连接

2022-09-06 15:25:22

Wifi设备开发

2022-01-12 14:45:26

鸿蒙HarmonyOS应用

2010-02-07 13:31:49

Ubuntu连接

2021-03-16 16:07:37

物联网蓝牙连接IoT

2021-11-12 23:44:28

Windows 10Windows微软

2021-12-28 16:06:15

鸿蒙HarmonyOS应用

2023-09-20 11:46:54

蓝牙物联网IOT

2020-06-22 10:21:44

物联网蓝牙技术

2022-05-18 14:21:18

漏洞蓝牙低功耗蓝牙
点赞
收藏

51CTO技术栈公众号