HarmonyOS-NEXT-程序访问控制权限
目录
HarmonyOS NEXT 程序访问控制(权限)
应用权限保护对象
当应用访问操作目标对象,目标对象对应用进行权限检查,如果没有权限访问操作被拒绝
应用权限等级说明
应用权限的等级说明====应用权限的申请优先级
APL三个等级 (应用APL等级不允许配置为system_core。)
|| ===system-core (操作系统核心能力) ——》暂不向任何三方应用开放
APL =======|| ===system-basic(系统基础服务)——》系统设置,身份认证
|| ===normal (普通应用)——》数据/功能
授权方式:权限类型
权限组和子权限
减少系统弹出的权限弹窗数量,优化交互体验,系统将逻辑紧密相关的user_grant权限组合在一起,形成多个权限组。
当应用请求权限时,同一个权限组的权限将会在一个弹窗内一起请求用户授权。权限组中的某个权限,称之为该权限组的子权限。
权限组和权限的归属关系并不是固定不变的,一个权限所属的权限组有可能发生变化。
应用申请权限的方式
配置声明权限
- 在 module.json5 中添加权限说明
注意:权限为 user_grant 时,还需添加授权原因。
添加 reason 权限使用理由
当申请的权限为 user_grant 权限时必填,并且需要进行多语种适配。
参考句式:用于某事,如:(麦克风)用于录制加密视频和音频。
检查当前权限是否开启
static async checkPermissionGrant(permissionName: Permissions[]): Promise<boolean> {
// 获取应用程序的accessTokenID
let tokenId: number = 0;
try {
const bundleInfo: bundleManager.BundleInfo =
await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
const appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
return false; // 如果获取 accessTokenId 失败,则直接返回 false
}
// 校验应用是否被授予权限
try {
// 使用 Promise.all 等待所有权限检查完成
const results = await Promise.all(permissionName.map(async (item) => {
return await atManager.checkAccessToken(tokenId, item);
}));
// 检查所有权限是否都被授予
return results.every((item) =>
item === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
);
} catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
return false; // 异常情况下也返回 false
}
}
向用户申请权限:这里需要说明一下,
如果有权限容许拉起二次弹窗,那么在你第一次拒绝用户申请的时候可以再一次弹窗,当然你的模拟器版本要在Beta3以上。
//用户请求授权
static reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
// let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
promptAction.showToast({ message: '用户请求授权成功' })
//可以取消授权
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
atManager.requestPermissionOnSetting(context, permissions)
.then((data: Array<abilityAccessCtrl.GrantStatus>) => {
console.info('data:' + JSON.stringify(data));
})
.catch((err: BusinessError) => {
console.error('data:' + JSON.stringify(err));
});
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
promptAction.showToast({ message: '判断授权失败' })
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
应用权限组列表
使用须知:
当应用请求权限时,同一个权限组的权限将会在一个弹窗内一起请求用户授权,用户同意授权后,权限组内权限将被统一授权。地理位置、通讯录、通话记录、电话、信息、日历权限组除外。
以位置信息和相机权限组举例说明:
- 当应用只申请了权限ohos.permission.APPROXIMATELY_LOCATION(属于位置信息权限组)时,应用用户将收到一个请求位置信息的弹窗,包含单个权限的申请。
- 当应用同时申请权限ohos.permission.APPROXIMATELY_LOCATION和ohos.permission.LOCATION(均属于位置信息权限组)时,应用用户将收到一个请求位置信息的弹窗,包含两个权限的申请。
- 当应用同时申请权限ohos.permission.APPROXIMATELY_LOCATION(属于位置信息权限组)和ohos.permission.CAMERA(属于相机权限组)时,应用用户将收到请求位置信息、请求使用相机的两个弹窗。
列表:
位置:
相机:
麦克风:
通讯录:
日历:
运动数据:
- (目前不支持在2 in1设备上申请)
身体传感器:
- (仅穿戴设备可以申请)