随着物联网技术的发展,短距离通信技术如蓝牙成为了连接各种智能设备的关键。HarmonyOS NEXT作为面向未来的操作系统,不仅支持传统的蓝牙技术,还特别优化了低功耗蓝牙(BLE)的支持,使得开发者能够轻松实现设备间的高效数据交换。本文将通过具体案例介绍如何在HarmonyOS NEXT中实现BLE蓝牙扫描功能。

场景一:申请蓝牙权限

在开始任何蓝牙相关的操作之前,首先需要确保应用已经获得了必要的权限。对于BLE操作而言,ohos.permission.ACCESS_BLUETOOTH权限是必须的。为了请求该权限,我们可以使用abilityAccessCtrl模块中的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": [ 
        "bluetooth" 
      ], 
      "when":"always" 
    } 
  }, 
]
场景二:BLE蓝牙扫描

一旦获得了必要的权限,接下来就可以开始进行BLE设备的扫描了。HarmonyOS NEXT提供了ble模块来处理BLE相关的操作。下面的代码展示了如何启动BLE扫描并处理扫描结果:

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 = {}; 
              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%') 
  } 
}
场景三:蓝牙模块能力展示

除了基本的BLE扫描功能,HarmonyOS NEXT还提供了丰富的蓝牙模块API,包括但不限于:

⦁    开启蓝牙:access.enableBluetooth。

⦁    关闭蓝牙:access.disableBluetooth。

⦁    获取蓝牙配对列表:connection.getPairedDevices。

⦁    获取蓝牙配对状态:connection.getPairState。

⦁    订阅蓝牙设备发现上报事件:connection.on('bluetoothDeviceFind')。

⦁    取消订阅蓝牙设备发现上报事件:connection.off('bluetoothDeviceFind')。

⦁    开启蓝牙扫描,可以发现远端设备:connection.startBluetoothDiscovery。

⦁    关闭蓝牙扫描:connection.stopBluetoothDiscovery。

⦁    发起蓝牙配对:connection.pairDevice。

⦁    创建一个服务端监听Socket:socket.sppListen。

这些功能的实现依赖于@ohos.bluetooth.access@ohos.bluetooth.connection@ohos.bluetooth.socket等模块。例如,开启蓝牙的代码如下:

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); 
  } 
})