HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备鉴权
HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备鉴权
前言
在鸿蒙系统(HarmonyOS)的广阔生态中,蓝牙作为一项基础且强大的无线连接技术,扮演着至关重要的角色。无论是智能家居设备的互联,还是健康监测手环的数据同步,都离不开蓝牙的支持。然而,在充分利用蓝牙功能之前,进行严格的权限检测是确保用户隐私安全、提升应用兼容性和用户体验的必要步骤。
首先,开发者需要确保目标设备支持蓝牙功能并且已经开启蓝牙开关。这可以通过鸿蒙系统提供的API接口进行查询,这里使用@kit.ConnectivityKit(蓝牙access模块)来检查设备是否开启蓝牙功能和订阅蓝牙设备开关状态事件,注意使用前需要配置权限:ohos.permission.ACCESS_BLUETOOTH
。
接下来,权限请求成为关键。在鸿蒙系统中,应用需要明确声明其所需的蓝牙权限,并在运行时向用户请求这些权限。并在用户首次使用蓝牙功能时,通过系统弹窗或应用内提示的方式请求用户授权。这一过程不仅是对用户隐私的尊重,也是遵守系统安全策略的重要体现。
获得用户授权后,应用才能开始执行蓝牙扫描、设备发现、连接与通信等操作。在这一过程中,鸿蒙系统还提供了丰富的API和工具,帮助开发者优化蓝牙连接的稳定性、降低功耗,并提升数据传输的效率。
综上所述,鸿蒙系统下的蓝牙使用权限检测是一个多环节、严要求的过程。它不仅关乎技术实现的细节,更体现了对用户隐私、系统安全和用户体验的高度重视。通过这一流程,鸿蒙系统为开发者提供了强大的蓝牙支持,也为用户带来了更加便捷、安全、高效的蓝牙体验。
蓝牙鉴权流程分析
在鸿蒙系统中,确保用户隐私和数据安全是首要任务之一,特别是在涉及蓝牙这样的敏感功能时。因此,核心点在于用户必须明确同意授权后,应用才能调用蓝牙相关的能力。以下是对这一流程的具体描述:
1. 初始状态检查
应用启动并准备使用蓝牙功能时,首先会检查用户是否已经授权蓝牙权限。这一步骤至关重要,因为它决定了应用是否有权进一步操作蓝牙设备。
- 授权状态检查:通过鸿蒙系统提供的API接口,应用能够查询当前是否已经获得了蓝牙权限。
2. 授权情况处理
根据授权检查的结果,应用会采取不同的行动:
-
已授权:如果应用已经获得了蓝牙权限,并且系统蓝牙功能也已打开,那么应用可以直接进入下一步操作,如扫描附近的蓝牙设备、建立连接等。
-
未授权:如果应用尚未获得蓝牙权限,系统将自动调起权限请求界面,引导用户进行授权。
3. 权限请求与响应
在权限请求界面,用户有两个选择:同意或不同意。
-
用户同意:如果用户选择同意授权,系统将允许应用访问蓝牙功能,并通知应用蓝牙权限已获取。此时,应用可以再次检查蓝牙功能是否已打开(因为有时用户可能关闭了蓝牙),如果蓝牙已打开,则进入下一步操作。
-
用户不同意:如果用户选择不同意授权,系统将通知应用无法访问蓝牙功能。此时,应用应该给出明确的提示,告知用户由于未授权,无法进入下一步操作,并可能建议用户检查权限设置或联系技术支持。
蓝牙鉴权流程封装
接下来,根据鉴权流程分析,我们来做下流程的封装
新建鉴权模块单例
这里以翼康养老项目封装为例:
- 检查蓝牙授权方法
- 请求用户授权方法
- 检查蓝牙功能
class EcBlueAuth {
checkBluePermission() {}
reqUserPermission() {}
isBlueOpen() {}
}
export const ecBlue = new EcBlueAuth()
检查蓝牙授权方法
- 获取应用信息
import bundleManager from '@ohos.bundle.bundleManager';
import { BusinessError } from '@ohos.base';
import hilog from '@ohos.hilog';
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
try {
bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
hilog.info(0x0000, 'testTag', 'getBundleInfoForSelf successfully. Data: %{public}s', JSON.stringify(data));
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed. Cause: %{public}s', err.message);
});
} catch (err) {
let message = (err as BusinessError).message;
hilog.error(0x0000, 'testTag', 'getBundleInfoForSelf failed: %{public}s', message);
}
- 调用检查授权方法
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let tokenID: number = 0; // 系统应用可以通过bundleManager.getApplicationInfo获取,普通应用可以通过bundleManager.getBundleInfoForSelf获取
let permissionName: Permissions = 'ohos.permission.GRANT_SENSITIVE_PERMISSIONS';
let data: abilityAccessCtrl.GrantStatus = atManager.checkAccessTokenSync(tokenID, permissionName);
console.log(`data->${JSON.stringify(data)}`);
- 获取授权信息
权限点:let permissionName: Permissions = ohos.permission.ACCESS_BLUETOOTH
async checkBluePermission() {
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
try {
// 1. 获取应用信息
const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags)
// 2. 检查蓝牙权限
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// let tokenID: number = 0; // 系统应用可以通过bundleManager.getApplicationInfo获取,普通应用可以通过bundleManager.getBundleInfoForSelf获取
let permissionName: Permissions = 'ohos.permission.ACCESS_BLUETOOTH';
let data: abilityAccessCtrl.GrantStatus = atManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissionName);
Log.info('蓝颜权限:' + data)
} catch (err) {
let message = (err as BusinessError).message;
Log.error(message)
}
}
- 授权页面使用
// 确认选择
Column() {
Button('确认')
.width(312)
.backgroundColor(ResManager.EC_MAIN_COLOR)
.onClick(() => {
ecBlue.checkBluePermission()
})
.enabled(this.selectedProd ? true : false)
}
- 执行结果
返回-1说明未授权
请求用户蓝牙授权
- 校验授权信息
async checkBluePermission() {
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
try {
// 1. 获取应用信息
const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags)
// 2. 检查蓝牙权限
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// let tokenID: number = 0; // 系统应用可以通过bundleManager.getApplicationInfo获取,普通应用可以通过bundleManager.getBundleInfoForSelf获取
let permissionName: Permissions = 'ohos.permission.ACCESS_BLUETOOTH';
let data: abilityAccessCtrl.GrantStatus = atManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissionName);
Log.info('蓝牙权限:' + data)
if(data === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
this.reqUserPermission()
return
}
} catch (err) {
let message = (err as BusinessError).message;
Log.error(message)
}
}
- 未授权情况:请求用户授权
import abilityAccessCtrl, { Context, PermissionRequestResult } from '@ohos.abilityAccessCtrl';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
let context: Context = getContext(this) as common.UIAbilityContext;
atManager.requestPermissionsFromUser(context, ['ohos.permission.CAMERA'], (err: BusinessError, data: PermissionRequestResult) => {
if (err) {
console.error(`requestPermissionsFromUser fail, err->${JSON.stringify(err)}`);
} else {
console.info('data:' + JSON.stringify(data));
console.info('data permissions:' + data.permissions);
console.info('data authResults:' + data.authResults);
}
});
reqUserPermission() {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
let context: Context = getContext(this) as common.UIAbilityContext;
atManager.requestPermissionsFromUser(context, ['ohos.permission.ACCESS_BLUETOOTH'],
(err: BusinessError, data: PermissionRequestResult) => {
if (err) {
Log.error(`requestPermissionsFromUser fail, err->${JSON.stringify(err)}`);
} else {
Log.info('data:' + JSON.stringify(data));
if (data.authResults[0] === 0) {
AlertDialog.show({
message: '已授权'
})
} else {
// 未授权
AlertDialog.show({
message: '请前往系统页面授权蓝牙权限后,才能继续绑定操作!'
})
}
}
});
}
检查蓝牙功能开关
获取蓝牙开关状态。
需要权限:ohos.permission.ACCESS_BLUETOOTH
系统能力:SystemCapability.Communication.Bluetooth.Core
。
import { BusinessError } from '@ohos.base';
try {
let state = access.getState();
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
- 配置蓝牙权限
"requestPermissions": [
// ...
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "$string:app_name",
"usedScene": {
"abilities": [ "EntryAbility" ],
"when": "inuse"
}
}
]
- 封装蓝牙是否打开方法
isBlueOpen() {
try {
const state = access.getState()
if (state === access.BluetoothState.STATE_ON) {
return true
} else {
return false
}
} catch (e) {
Log.error('ble_demo_log' + e.message)
return false
}
}
- 鉴权使用
async checkBluePermission() {
let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
try {
// 1. 获取应用信息
const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags)
// 2. 检查蓝牙权限
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// let tokenID: number = 0; // 系统应用可以通过bundleManager.getApplicationInfo获取,普通应用可以通过bundleManager.getBundleInfoForSelf获取
let permissionName: Permissions = 'ohos.permission.ACCESS_BLUETOOTH';
let data: abilityAccessCtrl.GrantStatus = atManager.checkAccessTokenSync(bundleInfo.appInfo.accessTokenId, permissionName);
Log.info('蓝牙权限:' + data)
if (data === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
// 未授权:请求用户授权
this.reqUserPermission()
return
}
if (!this.isBlueOpen()) {
AlertDialog.show({ message: '请打开蓝牙开关再试!' })
return
}
Log.warn('go')
} catch (err) {
let message = (err as BusinessError).message;
Log.error(message)
}
}
reqUserPermission() {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// 使用UIExtensionAbility:将common.UIAbilityContext 替换为common.UIExtensionContext
let context: Context = getContext(this) as common.UIAbilityContext;
atManager.requestPermissionsFromUser(context, ['ohos.permission.ACCESS_BLUETOOTH'],
(err: BusinessError, data: PermissionRequestResult) => {
if (err) {
Log.error(`requestPermissionsFromUser fail, err->${JSON.stringify(err)}`);
} else {
Log.info('data:' + JSON.stringify(data));
if (data.authResults[0] === 0) {
if(this.isBlueOpen()) {
Log.info('go')
}else {
AlertDialog.show({ message: '请打开蓝牙开关再试!' })
}
} else {
// 未授权
AlertDialog.show({
message: '请前往系统页面授权蓝牙权限后,才能继续绑定操作!'
})
}
}
});
}
鉴权通过操作封装
问题:如何满总条件后,执行特定逻辑?
- 检查授权和请求授权添加回调
async checkBluePermission(cb?: () => void) {
// ...
try {
// 1. 获取应用信息
const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleFlags)
// 2. 检查蓝牙权限
// ...
if (data === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
// 未授权:请求用户授权
this.reqUserPermission(cb)
return
}
if (!this.isBlueOpen()) {
AlertDialog.show({ message: '请打开蓝牙开关再试!' })
return
}
cb && cb()
// Log.warn('go')
} catch (err) {
let message = (err as BusinessError).message;
Log.error(message)
}
}
reqUserPermission(cb?: () => void) {
// ...
(err: BusinessError, data: PermissionRequestResult) => {
if (err) {
Log.error(`requestPermissionsFromUser fail, err->${JSON.stringify(err)}`);
} else {
Log.info('data:' + JSON.stringify(data));
if (data.authResults[0] === 0) {
if (this.isBlueOpen()) {
cb && cb()
// Log.info('go')
} else {
AlertDialog.show({ message: '请打开蓝牙开关再试!' })
}
} else {
// 未授权
AlertDialog.show({
message: '请前往系统页面授权蓝牙权限后,才能继续绑定操作!'
})
}
}
});
}
授权页面测试
// 2. 绑定
bindDevice() {
ecBlue.checkBluePermission(() => {
Log.info('鉴权通过!')
})
}
总结
将鉴权流程封装成一个独立的模块或类,可以在不同的应用或项目中重复使用,减少了重复编码的工作量,提高了开发效率。当鉴权流程需要更新或修复时,只需修改封装好的模块或类即可,无需在每个使用到鉴权的应用或项目中都进行修改,从而降低了维护成本。
综上所述,蓝牙鉴权流程封装的好处是多方面的,它不仅能够提高安全性、提升用户体验,还便于复用和维护,促进标准化和规范化。这些好处使得蓝牙技术在各种应用场景中更加可靠、高效和易用。
更多关于HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备鉴权的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备鉴权的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对帖子标题“HarmonyOS 鸿蒙Next 物联网Iot开发-BLE设备鉴权”的问题,以下是一个简洁的回答:
在HarmonyOS鸿蒙Next物联网(IoT)开发中,对于BLE(蓝牙低功耗)设备的鉴权,主要涉及到设备间的身份验证和数据加密。在鸿蒙系统中,可以通过以下方式实现BLE设备的鉴权:
-
配对与绑定:在BLE设备首次连接时,通过配对过程生成一个共享密钥。这个密钥用于后续通信中的数据加密和身份验证。
-
特征值读写权限:为BLE设备的特征值设置读写权限,只有经过鉴权的设备才能访问或修改这些特征值。
-
安全连接:使用蓝牙的安全连接功能(如LE Secure Connections),确保设备在连接过程中的数据传输是加密和安全的。
-
证书验证:对于需要更高安全性的应用,可以引入数字证书机制,对BLE设备进行身份验证,确保只有合法的设备才能接入系统。
在鸿蒙系统中,开发者可以利用系统提供的API和框架,方便地实现上述鉴权机制。如果开发者在开发过程中遇到具体问题,如API使用不当或功能实现上的疑问,可以参考鸿蒙系统的官方文档或开发指南。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html