HarmonyOS 鸿蒙Next如何查询App是否已经申请过某个权限

发布于 1周前 作者 yuanlaile 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next如何查询App是否已经申请过某个权限

【关键字】

调用 / system_grant(系统授权)/ user_grant(用户授权) / 访问权限控制

【问题描述】

问题一:

每次调用某个需要授权的场景时,App内想弹出自定义弹框给用户解释对应权限用途再去拉起系统授权弹框,当用户拒绝/允许后再次校验权限时不应该再次弹出自定义弹框。是否有对应API查询用户已申请过某个权限。

问题二:

第一次申请某权限时,在系统弹窗之前自定义弹窗解释该权限用途,之后再次弹窗申请不再弹出自定义弹窗实现方式是想如requestPermissionsFromUser这个接口一样,判断是否第一次弹窗,如果是第一次弹窗则拉起,否则不拉起,这个接口内部实现是如何实现的?

【解决方案】

问题一:

根据授权方式的不同,权限类型可分为system_grant(系统授权)和user_grant(用户授权)system_grant指的是系统授权类型,在该类型的权限许可下,应用被允许访问的数据不会涉及到用户或设备的敏感信息,应用被允许执行的操作不会对系统或者其他应用产生大的不利影响。

如果在应用中申请了system_grant权限,那么系统会在用户安装应用时,自动把相应权限授予给应用。

user_grant指的是用户授权类型,在该类型的权限许可下,应用被允许访问的数据将会涉及到用户或设备的敏感信息,应用被允许执行的操作可能对系统或者其他应用产生严重的影响。该类型权限不仅需要在安装包中申请权限,还需要在应用动态运行时,通过发送弹窗的方式请求用户授权。在用户手动允许授权后,应用才会真正获取相应权限,从而成功访问操作目标对象。如需检查用户是否已向您的应用授予特定权限,可以使用checkAccessToken函数,此方法会返回 PERMISSION_GRANTED或PERMISSION_DENIED。

具体的示例代码可参考:

async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
// 获取应用程序的accessTokenID
let tokenId: number = 0;
try {
let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(Failed to get bundle info <span class="hljs-keyword"><span class="hljs-keyword">for</span></span> self. Code is ${err.code}, message is ${err.message});
}

// 校验应用是否被授予权限 try { grantStatus = await atManager.checkAccessToken(tokenId, permission); } catch (error) { let err: BusinessError = error as BusinessError; console.error(Failed to check access token. Code is ${err.code}, message is ${err.message}); } return grantStatus; }

async checkPermissions(): Promise<void> { const permissions: Array<Permissions> = [‘ohos.permission.READ_CALENDAR’]; let grantStatus: abilityAccessCtrl.GrantStatus = await this.checkAccessToken(permissions[0]); if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { // 已经授权,可以继续访问目标操作 } else { // 申请日历权限 } }

访问权限控制相关的详细步骤和接口可参考文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-user-authorization-0000001774279718

问题二:

场景类似于首次打开页面的介绍页,可以通过本地数据库比如Preference存储来实现。

2 回复
根本无法知道是否向用户申请过授权,checkAccessToken 结果只有 DENIED(未授权)、GRANTED(已授权),但是实际上未授权分两种情况,一种是未向用户申请过授权,一种是向用户申请过授权但用户拒绝授权。而我目前的业务正是需要区分未授权的这两种情况,但是无法分辨。(ps:iOS就考虑得周到,有 NotDetermined(用户尚未做出选择)这种状态)

在HarmonyOS中,查询App是否已经申请过某个权限,主要依赖于系统API和权限管理框架。HarmonyOS提供了checkAccessToken这样的API来检查应用是否已被授予了特定的权限。这个API会返回PERMISSION_GRANTEDPERMISSION_DENIED,分别表示权限已被授予或未被授予。

具体实现时,你需要在代码中调用checkAccessToken函数,并传入你想要检查的权限标识符(如ohos.permission.READ_CALENDAR)。函数将返回一个状态,表明应用是否已拥有该权限。

请注意,这个API仅告诉你权限的当前状态,而不直接显示应用是否“申请过”该权限。因为用户可能在安装应用时接受了权限,也可能在应用运行过程中通过系统设置拒绝了权限。

此外,HarmonyOS的权限管理也分为系统授权(system_grant)和用户授权(user_grant)。系统授权在应用安装时自动授予,不涉及用户交互;而用户授权则需要通过弹窗请求用户明确同意。

如果问题依旧没法解决,请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。这将为你提供更专业的帮助和解决方案。

回到顶部