场景描述

蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之前的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的BLE蓝牙称为低功耗蓝牙。BLE模块提供了对蓝牙操作和管理的方法。

场景一:申请蓝牙权限

方案

ACCESS\_BLUETOOTH 权限是很多蓝牙接口需要申请的,比如:ble.getConnectedBLEDevices(获取和当前设备连接的BLE设备)、ble.startBLEScan(发起BLE扫描流程)。这个权限是需要用户授权的,可以通过调用requestPermissionsFromUser()方法来实现。

不鼓励频繁弹窗打扰用户,如果用户拒绝授权,将无法再次拉起弹窗。需要应用引导用户在系统应用“设置”的界面中手动授予权限,参考文档:向用户申请授权

核心代码

requestPermissionsFromUser() {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  try {
    let context = getContext(this);
    atManager.requestPermissionsFromUser(context, ['ohos.permission.ACCESS_BLUETOOTH'], (err: BusinessError, data: PermissionRequestResult) => {
      console.info('data:' + JSON.stringify(data));
      console.info('data permissions:' + data.permissions);
      console.info('data authResults:' + data.authResults);
    });
  } catch (err) {
    console.log(`catch err->${JSON.stringify(err)}`);
  }
}

配置文件

module.json文件中申请相关权限,相关权限说明可参考文档:对所有应用开放

"requestPermissions":[
  {
    "name" : "ohos.permission.ACCESS_BLUETOOTH",
    "reason": "$string:module_desc",
    "usedScene": {
      "abilities": [
        "FormAbility"
      ],
      "when":"always"
    }
  },
  {
    "name" : "ohos.permission.DISCOVER_BLUETOOTH",
    "usedScene": {
      "abilities": [
        "FormAbility"
      ],
      "when":"always"
    }
  },
  {
    "name" : "ohos.permission.USE_BLUETOOTH",
    "usedScene": {
      "abilities": [
        "bluetouth"
      ],
      "when":"always"
    }
  },
]

场景二:BLE蓝牙扫描和系统设置蓝牙扫描

BLE为低功耗蓝牙,只能扫描到低功耗的蓝牙设备。

connection是经典蓝牙,如果想扫描到系统设置中的所有设备,可以调用此接口。

方案

ble扫描的是低功耗蓝牙,相比于connection扫描结果偏少,如果想要扫描到系统设置中的所有设备,需要去调用@ohos.bluetooth.connection模块中的connection.startbluetoothdiscovery。

核心代码

低功耗蓝牙扫描:ble.startBLEScan

import { BusinessError } from '@kit.BasicServicesKit';
import { ble } from '@kit.ConnectivityKit';

@Entry
@Component
struct Index {
  @State onReceiveEventData: string = ''
  @State isScan: boolean = false
  // ...

  build() {
    Row() {
      Column() {
        // 蓝牙扫描
        Button("startBLEScan")
          .onClick(() => {
            this.isScan = !this.isScan
            let onReceiveEvent = (data: Array<ble.ScanResult>) => {
              console.info('BLE scan device find result = ' + JSON.stringify(data));
              let dataString = JSON.stringify(data)
              this.onReceiveEventData = dataString
            }
            try {
              ble.on("BLEDeviceFind", onReceiveEvent);
              let scanFilter: ble.ScanFilter = {
                // deviceId:"xxxx",
                // name:"test",
                // serviceUuid:"xxxx"
              };
              console.info('scanFilter' + JSON.stringify(scanFilter))
              let scanOptions: ble.ScanOptions = {
                interval: 50,
                dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
                matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE,
              }
              ble.startBLEScan(null, scanOptions);
            } catch (err) {
              console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
              (err as BusinessError).message);
            }

          })
          .type(ButtonType.Capsule)
          .margin({ top: 4 })
          .backgroundColor('#ff1198ee')
          .width('67%')
          .height('4%')

        // ...

        Text(this.isScan ? this.onReceiveEventData : '蓝牙未开启扫描')
          .textAlign(TextAlign.Center)
          .fontSize(12)
          .border({ width: 1 })
          .padding(10)
          .margin(10)
          .width('80%')
          .height(200)
      }
      .width('100%')
    }
    .height('100%')
  }
}

经典蓝牙扫描:connection.startBluetoothDiscovery。

import { BusinessError } from '@kit.BasicServicesKit';
import connection from '@ohos.bluetooth.connection';

@Entry
@Component
struct Index {
  @State onReceiveEventData: string = ''
  @State isScan: boolean = false
  // ...

  build() {
    Row() {
      Column() {
        // 蓝牙扫描
        Button("startBluetoothDiscovery")
          .onClick(() => {
            this.isScan = !this.isScan
            let onReceiveEvent = (data: Array<string>) => {
              console.log('data length' + JSON.stringify(data));
              let dataString = JSON.stringify(data)
              this.onReceiveEventData = dataString
            }
            try {
              connection.on('bluetoothDeviceFind', onReceiveEvent);
              connection.startBluetoothDiscovery();
            } catch (err) {
              console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' +
              (err as BusinessError).message);
            }
          })
          .type(ButtonType.Capsule)
          .margin({ top: 4 })
          .backgroundColor('#ff1198ee')
          .width('67%')
          .height('4%')

        Text(this.isScan ? this.onReceiveEventData : '蓝牙未开启扫描')
          .textAlign(TextAlign.Center)
          .fontSize(12)
          .border({ width: 1 })
          .padding(10)
          .margin(10)
          .width('80%')
          .height(200)
      }
      .width('100%')
    }
    .height('100%')
  }
}

场景三:蓝牙模块能力展示

效果图

方案

相关接口能力:

  1. 开启蓝牙:access.enableBluetooth。
  2. 关闭蓝牙:access.disableBluetooth。
  3. 获取蓝牙配对列表:connection.getPairedDevices。
  4. 获取蓝牙配对状态:connection.getPairState。
  5. 订阅蓝牙设备发现上报事件:connection.on('bluetoothDeviceFind')。
  6. 取消订阅蓝牙设备发现上报事件:connection.off('bluetoothDeviceFind')。
  7. 开启蓝牙扫描,可以发现远端设备:connection.startBluetoothDiscovery。
  8. 关闭蓝牙扫描:connection.stopBluetoothDiscovery。
  9. 发起蓝牙配对:connection.pairDevice。
  10. 创建一个服务端监听Socket:socket.sppListen。

相关接口参考文档:@ohos.bluetooth.access (蓝牙access模块)@ohos.bluetooth.connection (蓝牙connection模块)@ohos.bluetooth.socket (蓝牙socket模块)

核心代码

GridItem(){
  Button('打开权限').onClick(() => {
    hilog.info(0x00000, TAG, '打开权限');
    this.requestPermissionsFromUser();
  })
}
.columnStart(0)
.columnEnd(1)
.rowStart(0)
.rowEnd(0)

GridItem() {
  Button('蓝牙-开启').onClick(() => {
    hilog.info(0x00000, TAG, '蓝牙-开启');
    try {
      access.enableBluetooth();
    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}

GridItem() {
  Button('蓝牙-关闭').onClick(() => {
    hilog.info(0x00000, TAG, '蓝牙-关闭');
    try {
      access.disableBluetooth();
    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}

GridItem() {
  Button('获取蓝牙配对列表&状态').onClick(() => {
    hilog.info(0x00000, TAG, '获取蓝牙配对列表');
    try {
      let result: Array<string> = connection.getPairedDevices();
      let index = 1;
      result.forEach(s => {
        let state = connection.getPairState(s)
        hilog.info(0x00000, TAG, '第%{public}s台设备,id-> %{public}s,状态为->%{public}s', index++, s, bluetoothBondStateMap.get(state));
      })
    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}
.columnStart(0)
.columnEnd(1)
.rowStart(1)
.rowEnd(1)

GridItem() {
  Button('订阅蓝牙设备发现上报事件').onClick(() => {
    hilog.info(0x00000, TAG, '订阅蓝牙设备发现上报事件。');
    try {
      connection.on('bluetoothDeviceFind', onReceiveEvent);
    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}
.columnStart(0)
.columnEnd(1)
.rowStart(2)
.rowEnd(2)
GridItem() {
  Button('取消订阅设备发现上报事件').onClick(() => {
    hilog.info(0x00000, TAG, '取消订阅设备发现上报事件');
    try {
      hilog.info(0x00000, TAG, '共发现了设备数量为-1#' + deviceSet.size);
      connection.off('bluetoothDeviceFind', onReceiveEvent);
      index = 1;

    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}
.columnStart(0)
.columnEnd(1)
.rowStart(3)
.rowEnd(3)

GridItem() {
  Button('蓝牙-开启扫描').onClick(() => {
    hilog.info(0x00000, TAG, '蓝牙-开启扫描');
    try {
      connection.startBluetoothDiscovery()
    } catch (err) {
      hilog.info(0x00000, TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
    }
  })
}

HarmonyOS码上奇行
5k 声望2.5k 粉丝