Harmony os Next——Ble蓝牙模块

devtools/2024/9/29 17:28:49/

Harmony os Next——Ble蓝牙模块的使用

  • 描述
  • 权限
  • 扫描Ble蓝牙设备
    • 传递扫描的Ble设备
    • 接收扫描到的Ble设备
    • 取消扫描Ble设备
  • 连接Ble设备
    • 断开连接
  • 发现服务
  • 订阅Ble特征值变化事件
    • 订阅特征值通知
    • 订阅特征值变化事件
    • 取消订阅特征值变化事件
  • 写入特征值

描述

本文将对Ble蓝牙模块的扫描、连接、订阅、发送指令等操作进行阐述。
需要导入如下依赖即可使用ble相关功能
import ble from '@ohos.bluetooth.ble'

权限

对Ble蓝牙进行操作需要系统权限和用户授权权限,其中系统权限包括ohos.permission.USE_BLUETOOTHohos.permission.DISCOVER_BLUETOOTH,用户授权权限包括ohos.permission.ACCESS_BLUETOOTH

扫描Ble蓝牙设备

其中ble.on("BLEDeviceFind", this.onReceiveEvent)为定义蓝牙扫描事件,即为如果扫描到Ble蓝牙设备就会回调到此方法中。同时也可以添加过滤事件Array<ScanFilter>,精确回调自己想要的设备,如果不需要进行过滤就赋值为null即可

  startScanBluetooth() {try {ble.on("BLEDeviceFind", this.onReceiveEvent) //订阅蓝牙let scanOptions: ble.ScanOptions = {interval: 500, //表示扫描结果上报延迟时间dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER, //表示扫描模式matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE, //表示硬件的过滤匹配模式}ble.startBLEScan(null, scanOptions)} catch (err) {LoggerJoy.error('BLEDeviceFind---> errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

传递扫描的Ble设备

从扫描到的蓝牙设备中筛选出自己想要的Ble设备,其中扫描的结果会返回很多DeviceName为空的设备,可以对其进行过滤,其中connectable为false,代表设备已经被配对;为true代表可连接。然后Emitter进行进程间的通信,将扫描到的设备传递到UI层或者其他需要的地方

  //扫描到的设备private onReceiveEvent(data: Array<ble.ScanResult>) {let bleObject = BluetoothStatusManager.getInstance()//如果在极短时间内发现新的设备,则不进行回调let curTime = new Date().getTime()let diff: number = curTime - bleObject.lastScanDeviceTimebleObject.lastScanDeviceTime = curTimeif (diff < 10) returntry {/** 从扫描到的蓝牙设备中筛选出自己想要的Ble设备* 其中扫描的结果会返回很多deviceName为空的设备,可以对其进行过滤* 其中connectable为false 代表设备已经被配对;为true代表可连接* */let requireDevices = data.filter((ble) => {return ble.deviceName.length > 0 && ble.connectable })// 进程中通信-将扫描到的设备传递到UI层// 定义一个eventId为1的事件,事件立即被传递// 发送eventId为1的事件,事件内容为eventDataemitter.emit({eventId: BluetoothStatusManager.BluetoothScanEventID,priority: emitter.EventPriority.IMMEDIATE}, {data: {'bleDevices': connectableDevices}})} catch (err) {LoggerJoy.error('BLEDeviceFind---> errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

接收扫描到的Ble设备

然后在UI层可以通过emitter.on订阅指定事件,来获取传递的ble设备

  getConnectableDevice(){//订阅eventId:1的事件-接受来自蓝牙扫描的设备let innerEvent: emitter.InnerEvent = {eventId: BluetoothStatusManager.BluetoothScanEventID}// 收到eventId为1的事件后执行回调函数emitter.on(innerEvent, (eventData: emitter.EventData) => {if (eventData.data === undefined) {LoggerJoy.info('BLEDeviceFind---> Scan device is empty!')return}let connectableDevice = eventData.data['bleDevices'] as Array<ble.ScanResult>//对扫描的ble设备进行处理})}

取消扫描Ble设备

在停止蓝牙扫描设备时,同样也需要通过emitter.off取消订阅蓝牙传递事件

  //停止扫描蓝牙设备stopScanBluetooth() {emitter.off(BluetoothStatusManager.BluetoothScanEventID) //断开订阅蓝牙扫描结果事件ble.stopBLEScan() //停止扫描蓝牙}

连接Ble设备

ble>蓝牙状态值备注STATE_DISCONNECTED0已断连STATE_CONNECTING1正在连接STATE_CONNECTED2已连接STATE_DISCONNECTING3正在断连ble>

通过device.connect()连接ble蓝牙设备,需要指定扫描ble蓝牙设备时返回的数据中的deviceId,此字断即为ble设备的MAC地址,此地址可能会在ble设备下线、断开连接情况下发生变化。
然后可以通过device.on('BLEConnectionStateChange')订阅此设备的连接状态

/** 连接蓝牙设备--通过ble Mac地址进行连接* */connectBleDevice(deviceId: string) {try {let objetClass = BluetoothStatusManager.instancelet device: ble.GattClientDevice = ble.createGattClientDevice(deviceId)LoggerJoy.info(`BLEDeviceFind---> start connection ble device`)device.connect()device.on('BLEConnectionStateChange', (state: ble.BLEConnectionChangeState) => {//0:STATE_DISCONNECTED 已断连//1:STATE_CONNECTING 正在连接//2:STATE_CONNECTED 已连接//3:STATE_DISCONNECTING 正在断连let connectState: ble.ProfileConnectionState = state.stateif (connectState === constant.ProfileConnectionState.STATE_CONNECTED) {//连接成功之后的事件处理} else if (connectState === constant.ProfileConnectionState.STATE_DISCONNECTED) {//已经断开连接}})} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

断开连接

在与设备断开连接时,也可以取消订阅连接状态事件

  disconnectionBleDevice(deviceId: string) {try {if (this.gattClientDevice) {this.gattClientDevice.disconnect()this.gattClientDevice.off('BLEConnectionStateChange')LoggerJoy.info(`BLEDeviceFind---> stop connection ble device`)}} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

发现服务

在连接ble设备之后可以进行发现服务操作,获取Ble设备的相关操作,例如读和写。其中包含Ble设备的ServiceUUID、特征值内容和描述符内容等

device.getServices().then((result: Array<ble.GattService>) => {//对服务进行操作}).catch((err: BusinessError) => {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)})

订阅Ble特征值变化事件

订阅特征值通知

只有在发现服务之后,通过发现服务所返回的数据,即可对特定特征值通知进行订阅

  /** 订阅通知消息-只有打开了订阅,才能接受特征值变化响应* */setNotificationChannel() {if (!this.gattServiceInfo || !this.gattClientDevice) {LoggerJoy.info('BLEDeviceFind---> bluetooth gattServiceInfo is undefined ');return}//在发现服务中返回的数据中,过滤出自己特定所需事件即可let readCharacteristic = readCharacteristics[0]try {LoggerJoy.info('BLEDeviceFind---> setCharacteristicChangeNotification finish')this.gattClientDevice?.setCharacteristicChangeNotification(readCharacteristic, true)} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);}}

订阅特征值变化事件

只有打开特征值通知订阅(上节内容),才能接受特征值变化响应。
然后通过 this.gattClientDevice?.on('BLECharacteristicChange')即可响应特征值变化事件

  onBleCharacteristicChange() {if (!this.gattClientDevice) {LoggerJoy.info('BLEDeviceFind---> bluetooth device is disconnected')return}try {this.gattClientDevice?.on('BLECharacteristicChange', (characteristicChangeReq: ble.BLECharacteristic) => {LoggerJoy.info(`BLEDeviceFind---> onBleCharacteristicChange: ${JSON.stringify(characteristicChangeReq)}`)} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

取消订阅特征值变化事件

  offBleCharacteristicChange() {if (!this.gattClientDevice) {LoggerJoy.info('BLEDeviceFind---> bluetooth device is disconnected')return}try {this.gattClientDevice.off('BLECharacteristicChange')LoggerJoy.info('BLEDeviceFind---> cancel BLECharacteristicChange')} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

写入特征值

同意需要在发现服务中过滤出写入特征值的服务。此处以传入Uint8Array为例,因为writeCharacteristic.characteristicValue所需要数据为ArrayBuffer,所以通过buffer.from(需要转换的数据).buffer进行转换。最后通过this.gattClientDevice?.writeCharacteristicValue(writeCharacteristic, ble.GattWriteType.WRITE)完成特征值写入事件。

  async writeCharacteristicValue(command: Uint8Array) {if (!this.gattServiceInfo || !this.gattClientDevice) {return}//从发现服务中过滤出写入事件let writeCharacteristic = writeCharacteristics[0]//Uint8Array转ArrayBufferwriteCharacteristic.characteristicValue = buffer.from(command).buffertry {this.gattClientDevice?.writeCharacteristicValue(writeCharacteristic, ble.GattWriteType.WRITE, ()=>{LoggerJoy.info('BLEDeviceFind---> writeCharacteristicValue success')})} catch (err) {LoggerJoy.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message)}}

http://www.ppmy.cn/devtools/45507.html

相关文章

Go 语言中的指针

在许多现代编程语言中&#xff0c;如 Java 和 .NET&#xff0c;程序员通常无法直接控制底层的内存管理。然而&#xff0c;Go 语言提供了这样的能力&#xff0c;同时限制了可能导致错误的操作&#xff0c;比如指针运算。 文章目录 1、Go 语言中指针的介绍1.1、什么是指针&#x…

14.Ollydbg的基本使用

上一个内容&#xff1a;13.优化界面化的游戏辅助 Ollydbg是一个调试工具&#xff0c;它可以一步一步的运行一个程序并且还能很直观的看到被调试程序的寄存器状态、栈状态。Ollydbg需要以管理员方式运行&#xff01; 下图附加程序是调试一个正在运行的进程&#xff1a; 点击了…

Asp.Net Core 实现分片下载的最简单方式

技术群里的朋友遇到了这个问题&#xff0c;起初的原因是他对文件增加了一个属性配置 fileResult.EnableRangeProcessing true;这个属性我从未遇到过&#xff0c;然后&#xff0c;去F1查看这个属性的描述信息也依然少的可怜&#xff0c;只有简单的描述为(获取或设置为 启用范围…

Pandas练习

一 题目要求 酒类消费数据 给定一个某段时间内各个国家的酒类消费数据表drinks.csv&#xff0c;其中包含6个字段&#xff0c;表8-1 给出了该表中的字段信息。 表8-1酒类消费数据表的字段信息 Country国家beer_servings啤酒消费量spirit_servings烈酒消费量wine_servings红酒消…

C#语言进阶(三) 元组

总目录 C# 语法总目录 元组目录 元组1. 元组元素命名2. 元组的解构3. 元组的比较 元组 元组(tuple)是一组存储值的便捷方式。 元组的目的主要是&#xff0c;不使用out参数而从方法中返回多个值。(匿名类型无法做这个操作)元组能做匿名类型所有操作。 元组是值类型&#xff0…

【自动驾驶技术】自动驾驶汽车AI芯片汇总——地平线篇

0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0c;虽然参考了他人的宝贵见解及成果&#xff0c;但是内容可能存在不准确的地方。如果发现文中错误&#xff0c;希望批评指正&#xff0c;共同进步。 本篇文章是这个系列的第二篇&#x…

从CSV到数据库(简易)

需求&#xff1a;客户上传CSV文档&#xff0c;要求CSV文档内容查重/插入/更新相关数据。 框架&#xff1a;jdbcTemplate、commons-io、 DB&#xff1a;oracle 相关依赖&#xff1a; 这里本来打算用的2.11.0&#xff0c;无奈正式项目那边用老版本1.3.1&#xff0c;新版本对类型…

SourceTree跳过注册方法跳过注册页

方法一&#xff1a; 1.打开SourceTree 2.关闭SourceTree 3.命令终端输入 defaults write com.torusknot.SourceTreeNotMAS completedWelcomeWizardVersion 3 4.打开SourceTree即可跳过登录 方法二&#xff1a; 1.关闭SourceTree 2.右键SourceTree选择【显示包内容】 3.在Conten…