首页 > 其他分享 >OpenHarmony BLE蓝牙连接

OpenHarmony BLE蓝牙连接

时间:2023-04-21 23:06:10浏览次数:42  
标签:OpenHarmony connectState 蓝牙 bluetooth ohos BLE 设备

OpenHarmony BLE蓝牙设备连接

1. 简介

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

文末有项目代码

2.设备与环境

设备:九联s905l3a机顶盒、开鸿智谷学生卡BLE蓝牙设备

系统:OpenHarmony 3.2 beta2

SDK:9

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

3.逻辑流程

OpenHarmony BLE蓝牙连接_BLE蓝牙连接

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

4.实现过程
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"
        }
      }
    ]
4.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,
      });
    }
  }
4.3 注册发现BLE设备监听器

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

OpenHarmony BLE蓝牙连接_BLE蓝牙连接_02

通过注册发现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.4 开启BLE设备扫描

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

OpenHarmony BLE蓝牙连接_BLE蓝牙连接_03

在这里,我设置只扫描包含我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,
      }
    )
4.5 连接BLE设备

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

OpenHarmony BLE蓝牙连接_BLE蓝牙连接_04

// 订阅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蓝牙连接_BLE蓝牙连接_05

// 连接蓝牙
let BLEConnect = this.BLEDevice.connect()
// 如果连接成功,则把BLE设备存入连接成功列表
if(BLEConnect){
	this.deviceBleList.push(item)
}
4.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/#bkwz


标签:OpenHarmony,connectState,蓝牙,bluetooth,ohos,BLE,设备
From: https://blog.51cto.com/harmonyos/6205722

相关文章

  • boot-admin整合flowable官方editor-app源码进行BPMN2-0建模(续)
    boot-admin整合flowable官方editor-app源码进行BPMN2-0建模(续)书接上回项目源码仓库github项目源码仓库giteeboot-admin是一款采用前后端分离模式、基于SpringCloud微服务架构的SaaS后台管理框架。系统内置基础管理、权限管理、运行管理、定义管理、代码生成器和办公管理6个功......
  • k8s-系列:1.镜像仓库harbor之ansible-playbook安装
    一.准备环境:1.centos7环境2.安装ansible环境3.harbor安装文件下载路径:   https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v2.5.3/harbor-offline-installer-v2.5.3.tgz4.harbor安装,作者用192.168.126.129作为harbor安装环境 harbor安装分......
  • WebStorm 2023.1 vue文件标签中变量无法识别 Unresolved variable or type
    从老版本WebStorm升级到 WebStorm2023.1之后,打开项目莫名爆红 可能是查询的不对,很多博客指明是依赖的问题,实际修改无效问题出在文件类型指向不对修改为: 问题解决 ......
  • 猛读论文6 |【CVPR 2022】Camera-Conditioned Stable Feature Generation for Isolate
    用于孤立摄像机监督行人重识别的摄像机条件稳定特征生成动机常规ReID,对于一个ID,在不同摄像头拍摄的图片上提取跨相机视图不变特征而ISCS情况下,无法做到同一个ID采集到不同摄像头图片由于跨相机样本在人体Re-ID模型训练中起着重要作用,而在ISCS设置下不存在此类配对图像,因......
  • 蓝牙Sig Mesh 概念入门③——分层结构Layered architecture
    文章目录一、Modellayer二、FoundationModellayer三、Accesslayer四、Transportlayer五、Networklayer六、Bearerlayer一、Modellayermodel定义了一个节点支持的功能特性,每一个model都定义了自己的opcode和status。比如genericonoffmodel,定义了GenericON/OFF/G......
  • 蓝牙Sig Mesh 概念入门②——网络角色
    文章目录一、前言二、Provisioner(配置节点)三、Proxy(代理节点)四、Node(普通节点)一、前言SigMesh组成了一个大网,里面有很多设备。包括协助设备入网的网关,终端的执行者节点,实际的控制者手机App等。他们分别作为什么角色,有着什么关系?二、Provisioner(配置节点)将未入网的设备引导入网的......
  • Swift CustomStringConvertible 协议的使用
    目录一、前言二、使用场景1.整型类型的枚举使用2.Class类型的使用一、前言先看一下Swift标准库中对CustomStringConvertible协议的定义publicprotocolCustomStringConvertible{///Atextualrepresentationofthisinstance.//////Callingthispropert......
  • tableViewCell 自定义圆角
     在一个多cell的Tab了View中设置第一个和最后一个cell的圆角其实还是贝塞尔去画给cell加一个view -(void)tableView:(UITableView*)tableViewwillDisplayCell:(UITableViewCell*)cellforRowAtIndexPath:(NSIndexPath*)indexPath{  if(indexPath.row==0&&......
  • element-ui 的 table 组件 无法设置行高的问题?
    element-ui的table组件无法设置行高的问题因为需要改变table组件的行高;试了好多方法;包括官方文档提供的方法cell-style,cell-class-name,虽然能加上样式但是没有效果,不知道啥原因,最后发现td下面有个class为cell的div,于是修改如下.cell{max-height:94px!important;ove......
  • el-table合并行合并列
    1.合并多行objectSpanMethod({row,column,rowIndex,columnIndex},list){//console.log("objectSpanMethod",columnIndex,list)if(columnIndex===4||columnIndex===5||columnIndex===6){if(rowIndex==0){......