当前位置:   article > 正文

OpenHarmony多设备分布式组网认证_@ohos.distributedhardware.devicemanager

@ohos.distributedhardware.devicemanager

前提

安装好DevEco Studio,新建项目,选择API9版本,stage模型

点击Finish,此时,咱们的API9项目就算创建成功啦~

替换Full-SDK

参考OpenAtom OpenHarmony

必要权限

ohos.permission.DISTRIBUTED_DATASYNC

允许不同设备间的数据交换

权限级别:normal

授权方式:user_grant

ACL使能:TRUE

###

ohos.permission.DISTRIBUTED_SOFTBUS_CENTER

允许不同设备之间进行组网处理。

权限级别:system_basic

授权方式:system_grant

ACL使能:FALSE

权限申明

首先,在项目的模块级目录下找到并打开module.json5文件,在module下的对象里添加如下申明:

  1. "requestPermissions": [
  2. {
  3. "name": "ohos.permission.DISTRIBUTED_DATASYNC",
  4. "reason": "$string:DataSync",
  5. "usedScene": {
  6. "abilities": [
  7. "EntryAbility"
  8. ],
  9. }
  10. },
  11. {
  12. "name": "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER"
  13. }
  14. ]

此时,配置文件中的权限申明就完成了,但是,此时我们还不能获得这些权限。由于ohos.permission.DISTRIBUTED_DATASYNC权限是ACL使能为TRUE的权限,咱们需要在签名工具文件中说明一下。如何找到对应的签名工具文件呢?我们在安装DevEco Studio的时候是下载好了OpenHarmony的SDK的,此时在OpenHarmony文件夹中,打开 “你的SDK版本\toolchains\lib” 该路径,此时在lib文件夹中,咱们可以找到两个json文件,分别为UnsgnedDebugProfileTemplate.json和UnsgnedReleasedProfileTemplate.json,点击并打开这两个文件,添加如下权限:

"acls":{

"allowed-acls":[

"ohos.permission.DISTRIBUTED_DATASYNC"

]

}

此时咱们不着急关闭这两个文件,因为在我们申请的权限中,有一个权限是允许我们使用系统能力的,也就是说,我们申请的这个权限是一个系统权限,

ohos.permission.DISTRIBUTED_SOFTBUS_CENTER是一个系统权限,其权限级别为system_basic,授权方式为system_grant,此时,咱们需要再次修改刚刚打开的文件,找到"bundle-info"标签,修改“apl”标签内容和“app-feature”标签内容如下:

"apl":"system_basic",

"app-feature":"hos_system_app"

OK,接下来开始编码了

在申请ohos.permission.DISTRIBUTED_DATASYNC权限时,其文档中将其标注为用户手动授权的权限,此时需要我们动态申请权限,在项目中,我们新建一个ets文件,我这里取名为RequestPermission.ets

首先,导入以下包:

  1. import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
  2. import bundleManager from '@ohos.bundle.bundleManager';
  3. import common from '@ohos.app.ability.common';

获取访问控制模块对象实例:

let atManager = abilityAccessCtrl.createAtManager();

编写如下方法(这里我使用的是异步函数):

  1. export async function checkAccessTokenID(permission: Array<Permissions>) {
  2. // 获取应用程序的accessTokenID
  3. let tokenId: number;
  4. let grantStatus: Array<abilityAccessCtrl.GrantStatus> = []
  5. try {
  6. let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
  7. let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
  8. tokenId = appInfo.accessTokenId;
  9. } catch (err) {
  10. console.error(`getBundleInfoForSelf failed, code is ${err.code}, message is ${err.message}`);
  11. }
  12. // 校验应用是否被授予权限,若申请多个权限,建议循环检查多个权限
  13. for (let index = 0;index < permission.length; index++) {
  14. try {
  15. grantStatus.push(await atManager.checkAccessToken(tokenId, permission[index]))
  16. } catch (err) {
  17. console.error(`checkAccessToken failed, code is ${err.code}, message is ${err.message}`);
  18. }
  19. }
  20. return grantStatus;
  21. }
  22. export async function checkPermission(context: common.UIAbilityContext, permissions: Array<Permissions>) {
  23. let grantStatus: Array<abilityAccessCtrl.GrantStatus> = await checkAccessTokenID(permissions)
  24. for (let i = 0; i < grantStatus.length; i++) {
  25. if (grantStatus[i] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
  26. console.info(`${permissions[i].toString()} 已授权`)
  27. } else {
  28. //申请权限
  29. console.info('开始向用户申请权限')
  30. requestPermissionFromUser(context, permissions)
  31. }
  32. }
  33. }
  34. export async function requestPermissionFromUser(context: common.UIAbilityContext, permissions: Array<Permissions>) {
  35. // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  36. atManager.requestPermissionsFromUser(context, permissions).then((data) => {
  37. let grantStatus: Array<number> = data.authResults
  38. let length: number = grantStatus.length
  39. for (let i = 0;i < length; i++) {
  40. if (grantStatus[i] === 0) {
  41. // 用户授权,可以继续访问目标操作
  42. console.info(`${permissions[i].toString()} 权限申请成功`)
  43. } else {
  44. // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
  45. console.info(`${permissions[i].toString()} 权限申请被用户拒绝`)
  46. }
  47. }
  48. // 授权成功
  49. })
  50. }

此时,我们申请权限的方法就算编写完成了,在应用入口,即EntryAbility.ts文件中的onCreate(want: Want, launchParam: AbilityConstant.LaunchParam)方法中回调权限申请函数:

requestPermissionFromUser(this.context, PERMISSIONS)

其中,PERMISSIONS定义如下:

const PERMISSIONS: Array<Permissions> = ['ohos.permission.DISTRIBUTED_DATASYNC']

到此,我们的权限申请就算完完全全完成啦,当用户第一次安装并打开应用的时候,应用会向用户通过弹窗形式申请权限,用户点击授权即可赋予应用相应的权限啦~

多设备组网认证

在开始编码之前,新建一个ets文件,我给它命名为DistributedDeviceManagerFunctions.ets

首先,导入所需包:

import deviceManager from '@ohos.distributedHardware.deviceManager'

由于咱们多设备组网认证功能中需要使用到一些共享对象,所以我的设计方法是设计一个类,并将方法和对象封装到该类中,方便调用:

  1. export class DistributedDeviceManageFunc {
  2. }

定义类中对象:

  1. static mDeviceManager: deviceManager.DeviceManager
  2. static subscribeId: number
  3. static publishId: number
  4. static distributedDeviceList: Array<deviceManager.DeviceInfo> = []

初始化类

  1. static init() {
  2. deviceManager.createDeviceManager(globalThis.context.abilityInfo.bundleName, (error, data) => {
  3. if (error) {
  4. console.error(`create device manager failed,error:${JSON.stringify(error)}`)
  5. return
  6. }
  7. this.mDeviceManager = data
  8. console.info('create device manager successfully')
  9. try {
  10. this.publishId = Math.floor(Math.random() * 10000 + 1000)
  11. data.publishDeviceDiscovery({
  12. publishId: this.publishId,
  13. mode: deviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE,
  14. freq: deviceManager.ExchangeFreq.HIGH,
  15. ranging: false
  16. })
  17. console.info('publishDeviceDiscovery successfully')
  18. } catch (error) {
  19. console.error(`publishDeviceDiscovery failed,error:${JSON.stringify(error)}`)
  20. }
  21. try {
  22. data.on('publishSuccess', (data) => {
  23. console.info("publishSuccess:" + JSON.stringify(data))
  24. })
  25. console.info('publishSuccess on successfully')
  26. } catch (error) {
  27. console.error(`publishSuccess failed,error:${JSON.stringify(error)}`)
  28. }
  29. try {
  30. data.on('publishFail', (error) => {
  31. console.info("publishFail on:" + JSON.stringify(error))
  32. })
  33. console.info('publishFail on successfully')
  34. } catch (error) {
  35. console.error(`publishFail failed,error:${JSON.stringify(error)}`)
  36. }
  37. try {
  38. data.on('deviceStateChange', (data) => {
  39. console.info("deviceStateChange on:" + JSON.stringify(data))
  40. if (data.action == deviceManager.DeviceStateChangeAction.READY) {
  41. AppStorage.Set('statusColor', '#ff4fc100')
  42. } else if (data.action == deviceManager.DeviceStateChangeAction.OFFLINE) {
  43. AppStorage.Set('statusColor', '#ffff0000')
  44. } else if (data.action == deviceManager.DeviceStateChangeAction.ONLINE) {
  45. AppStorage.Set('statusColor', '#ffffd500')
  46. }
  47. })
  48. console.info('deviceStateChange on successfully')
  49. } catch (error) {
  50. console.error(`deviceStateChange failed,error:${JSON.stringify(error)}`)
  51. }
  52. })
  53. }

在该方法中,我们通过createDeviceManager(bundleName: string, callback: AsyncCallback): void函数创建了一个设备管理器实例,并将回调函数中得到的DeviceManager对象传递给先前定义的mDeviceManager.

以上操作完成后,使用publishDeviceDiscovery(publishInfo: PublishInfo): void函数发布周边设备发现,即调用该函数,主设备可以主动让周边(同一网络环境下)的设备发现识别:

  1. try {
  2. this.publishId = Math.floor(Math.random() * 10000 + 1000)
  3. data.publishDeviceDiscovery({
  4. publishId: this.publishId,
  5. mode: deviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE,
  6. freq: deviceManager.ExchangeFreq.HIGH,
  7. ranging: false
  8. })
  9. console.info('publishDeviceDiscovery successfully')
  10. } catch (error) {
  11. console.error(`publishDeviceDiscovery failed,error:${JSON.stringify(error)}`)
  12. }

注册设备状态回调,当设备状态发生改变时,可以通过on(type: ‘deviceStateChange’, callback: Callback<{ action: DeviceStateChangeAction, device: DeviceInfo }>): void获取设备状态改变后的第一状态:

  1. try {
  2. data.on('deviceStateChange', (data) => {
  3. console.info("deviceStateChange on:" + JSON.stringify(data))
  4. if (data.action == deviceManager.DeviceStateChangeAction.READY) {
  5. AppStorage.Set('statusColor', '#ff4fc100')
  6. } else if (data.action == deviceManager.DeviceStateChangeAction.OFFLINE) {
  7. AppStorage.Set('statusColor', '#ffff0000')
  8. } else if (data.action == deviceManager.DeviceStateChangeAction.ONLINE) {
  9. AppStorage.Set('statusColor', '#ffffd500')
  10. }
  11. })
  12. console.info('deviceStateChange on successfully')
  13. } catch (error) {
  14. console.error(`deviceStateChange failed,error:${JSON.stringify(error)}`)
  15. }

开始发现周边设备

使用startDeviceDiscovery(subscribeInfo: SubscribeInfo, filterOptions?: string): void函数可以使本设备暂时具有发现周边发布设备发现的设备的能力,即本设备可以识别周边设备:

  1. static startDeviceDiscovery() {
  2. try {
  3. this.subscribeId = Math.floor(Math.random() * 10000 + 1000)
  4. this.mDeviceManager.startDeviceDiscovery({
  5. subscribeId: this.subscribeId,
  6. mode: deviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE,
  7. medium: deviceManager.ExchangeMedium.AUTO,
  8. freq: deviceManager.ExchangeFreq.HIGH,
  9. isWakeRemote: false,
  10. isSameAccount: false,
  11. capability: deviceManager.SubscribeCap.SUBSCRIBE_CAPABILITY_OSD
  12. })
  13. this.mDeviceManager.on('deviceFound', (data) => {
  14. console.info('device found')
  15. console.info("deviceFound:" + JSON.stringify(data))
  16. this.distributedDeviceList = []
  17. if (this.distributedDeviceList.length == 0) {
  18. this.distributedDeviceList.push(data.device)
  19. AppStorage.Set('distributedDeviceList', this.distributedDeviceList)
  20. } else {
  21. var length = 0
  22. this.distributedDeviceList.forEach(element => {
  23. if (element.deviceId == data.device.deviceId) {
  24. return
  25. }
  26. length++
  27. })
  28. if (length == this.length) {
  29. this.distributedDeviceList.push(data.device)
  30. AppStorage.Set('distributedDeviceList', this.distributedDeviceList)
  31. }
  32. }
  33. })
  34. } catch (error) {
  35. console.error(`startDeviceDiscovery failed,error:${JSON.stringify(error)}`)
  36. }
  37. }

在该函数中,我们注册发现设备回调监听,当周边有可认证设备被发现时,该回调函数会返回 DeviceInfo类型的对象,其中为发现设备的部分设备信息:

  1. this.mDeviceManager.on('deviceFound', (data) => {
  2. console.info('device found')
  3. console.info("deviceFound:" + JSON.stringify(data))
  4. this.distributedDeviceList = []
  5. if (this.distributedDeviceList.length == 0) {
  6. this.distributedDeviceList.push(data.device)
  7. AppStorage.Set('distributedDeviceList', this.distributedDeviceList)
  8. } else {
  9. var length = 0
  10. this.distributedDeviceList.forEach(element => {
  11. if (element.deviceId == data.device.deviceId) {
  12. return
  13. }
  14. length++
  15. })
  16. if (length == this.length) {
  17. this.distributedDeviceList.push(data.device)
  18. AppStorage.Set('distributedDeviceList', this.distributedDeviceList)
  19. }
  20. }
  21. })

获取设备认证

在authenticateDevice(deviceInfo: DeviceInfo, authParam: AuthParam, callback: AsyncCallback<{deviceId: string, pinToken ?: number}>): void函数中,我们将所需配对的设备信息(DeviceInfo类型)作为参数传入即可触发设备认证,当两个设备没有相互认证时,回调该函数,对端设备上会弹出PIN码,在请求认证设备(本设备)中输入对端设备生成的PIN码即可完成设备认证

  1. static authenticateDevice(deviceInformation: deviceManager.DeviceInfo) {
  2. try {
  3. this.mDeviceManager.authenticateDevice(deviceInformation, {
  4. authType: 1,
  5. extraInfo: undefined
  6. }, (error, data) => {
  7. if (error) {
  8. console.error("authenticateDevice error:" + JSON.stringify(error))
  9. return
  10. }
  11. console.info("authenticateDevice result:" + JSON.stringify(data))
  12. })
  13. } catch (error) {
  14. console.error(`authenticateDevice error:${JSON.stringify(error)}`)
  15. }
  16. }

终止发现周边设备

  1. static stopDeviceDiscovery() {
  2. try {
  3. this.mDeviceManager.stopDeviceDiscovery(this.subscribeId)
  4. } catch (error) {
  5. console.error(`stopDeviceDiscovery failed,error:${JSON.stringify(error)}`)
  6. }
  7. }

获取可信任设备列表

当多个设备间完成相互认证时,调用该方法会获取完成认证的设备列表(deviceManager.DeviceInfo[]):

  1. static getTrustedDeviceListSync() {
  2. return this.mDeviceManager.getTrustedDeviceListSync()
  3. }

解除设备认证

  1. static unAuthenticateDevice(deviceInformation: deviceManager.DeviceInfo) {
  2. this.mDeviceManager.unAuthenticateDevice(deviceInformation)
  3. }

释放资源

  1. static release() {
  2. this.mDeviceManager.release()
  3. }

以上便是openHarmony中的多设备分布式组网认证过程,怎么样,你get到了吗 <_>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/242901
推荐阅读
相关标签
  

闽ICP备14008679号