Harmony os Next——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.lastScanDeviceTime
    bleObject.lastScanDeviceTime = curTime
    if (diff < 10) return
    try {
      /*
     * 从扫描到的蓝牙设备中筛选出自己想要的Ble设备
     * 其中扫描的结果会返回很多deviceName为空的设备,可以对其进行过滤
     * 其中connectable为false 代表设备已经被配对;为true代表可连接
     * */
      let requireDevices = data.filter((ble) => {
        return ble.deviceName.length > 0 && ble.connectable 
      })
      // 进程中通信-将扫描到的设备传递到UI层
      // 定义一个eventId为1的事件,事件立即被传递
      // 发送eventId为1的事件,事件内容为eventData
      emitter.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设备

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

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

/*
   * 连接蓝牙设备--通过ble Mac地址进行连接
   * */
  connectBleDevice(deviceId: string) {
    try {
      let objetClass = BluetoothStatusManager.instance
      let 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.state
        if (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转ArrayBuffer
    writeCharacteristic.characteristicValue = buffer.from(command).buffer

    try {
    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)
    }
  }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FranzLiszt1847

嘟嘟嘟嘟嘟

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值