HarmonyOS鸿蒙Next中怎么解决动态申请权限时,用户拒绝后无法再次触发弹窗?
HarmonyOS鸿蒙Next中怎么解决动态申请权限时,用户拒绝后无法再次触发弹窗? 动态申请ACCESS_DISTRIBUTED_NETWORK_STATE权限时,用户拒绝后无法再次触发弹窗,如何处理?
您好,可以参考以下解决方案:
【解决方案】
系统不鼓励频繁弹窗打扰用户,如果调用requestPermissionsFromUser()接口被用户拒绝授权,将无法再次拉起弹窗,此时可使用requestPermissionOnSetting()二次拉起权限弹窗,或者引导用户跳转到系统设置的权限页进行手动开启权限,具体操作如下:
1.权限检查: 申请相关权限前应使用checkAccessToken()检查是否有该权限,若无权限则进行如下操作。 使用requestPermissionsFromUser()接口请求相应的权限时,系统会拉起权限弹窗。示例代码如下:
import { abilityAccessCtrl, Context, PermissionRequestResult, common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
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);
console.info('data dialogShownResults:' + data.dialogShownResults);
}
});
2.二次向用户申请授权: 用户已经拒绝过该权限则不会再次弹起,需要引导用户开启权限有以下两种方案。
- 方案一: 调用requestPermissionOnSetting()二次拉起权限设置弹窗,示例代码如下:
import { abilityAccessCtrl, Context, common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let context: Context = getContext(this) as common.UIAbilityContext;
atManager.requestPermissionOnSetting(context, ['ohos.permission.CAMERA']).then((data: Array<abilityAccessCtrl.GrantStatus>) => {
console.info('data:' + JSON.stringify(data));
}).catch((err: BusinessError) => {
console.error('data:' + JSON.stringify(err));
});
注:不鼓励频繁调用requestPermissionOnSetting()进行权限请求。
- 方案二: 可以引导用户点击跳转到对应应用的权限页面,让用户手动授权,示例代码如下:
import { common } from '@kit.AbilityKit';
@Entry
@ComponentV2
struct SelectCollection {
build() {
Column() {
Button('跳转到对应应用的通知权限页').onClick(() => {
let context = getContext(this) as common.UIAbilityContext;
context.startAbility({
bundleName: 'com.huawei.hmos.settings',
abilityName: 'com.huawei.hmos.settings.MainAbility',
uri: 'systemui_notification_settings', // uri为空的时候,拉起设置主页面
parameters: {
pushParams: {
bundleName: 'com.example.multishopping' // 传要跳转的对应应用的包名
}
}
});
})
}
.width('100%')
.height('100%')
}
}
【常见FAQ】
Q:调用requestPermissionOnSetting()接口无法拉起系统二次授权弹窗,报错12100001。 A:参考错误码信息,二次授权需要保证当次申请的所有权限在同一个权限组中。
Q:在首次申请用户授权弹窗弹出时不进行选择授权方式,直接返回上一级、返回应用后台或退出应用会有什么结果? A:首次申请用户授权弹窗弹出时不进行选择授权方式直接返回,会默认用户选择拒绝授权,在应用权限设置页面可以看到应用对应权限为关闭状态;再次调用申请用户授权接口dialogShownResults参数会返回false,表示非首次调用申请用户授权接口。
Q:可以跳转应用总权限页,如何跳转到各自的权限详情页? A:目前不支持跳转到应用单个权限详情页。
Q:申请用户权限没有弹出对应的提示框? A:参考权限APP_TRACKING_CONSENT,部分权限在申请时,有开关去控制是否弹窗向用户请求授权。开关关闭,当应用请求权限时,系统不会弹窗,默认授予应用权限。
【总结】
当用户触发需要使用权限的场景时,首先使用checkAccessToken()判断当前是否已经授权,如果已经授权,则可以直接访问目标操作,否则需要向用户申请授权。调用requestPermissionsFromUser()方法可以向用户申请授权。若之前已经拒绝过该权限,可使用requestPermissionOnSetting()二次拉起权限弹窗,或者引导用户跳转到系统设置的权限页进行手动开启权限。
更多关于HarmonyOS鸿蒙Next中怎么解决动态申请权限时,用户拒绝后无法再次触发弹窗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
【背景知识】
[@ohos.abilityAccessCtrl(程序访问控制管理)](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-abilityaccessctrl):程序访问控制提供应用程序的权限校验和管理能力。
【参考方案】:
可参考考勤打卡位置获取示例,实现了多次向用户权限申请的交互效果。
- 调用requestPermissionsFromUser接口第一次拉起弹框请求用户授权;若用户拒绝授权,调用requestPermissionOnSetting接口,二次拉起权限设置弹框请求用户授权;若用户再次拒绝授权,则拉起跳转到设置页面的权限申请弹窗。
// 申请用户授权
async requestPermissions(context: UIContext, permissions: Array<Permissions>): Promise<boolean | undefined> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
try {
let data = await atManager.requestPermissionsFromUser(context.getHostContext() as common.UIAbilityContext, permissions)
return data.dialogShownResults ? data.dialogShownResults[0] : undefined; // 返回请求是否有弹窗
} catch (e) {
return undefined;
}
}
// 2次申请用户授权
requestPermissionsOnSetting(context: UIContext, permissions: Array<Permissions>) {
let keyPerms = JSON.stringify(permissions)
let store = preferences.getPreferencesSync(context.getHostContext(), { name: 'permsHasOnSetting' });
if (!store.hasSync(keyPerms)) {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionOnSetting(context.getHostContext(), permissions)
}
}
在HarmonyOS Next中,用户拒绝权限后,可通过调用abilityAccessCtrl
模块的requestPermissionsFromUser
方法再次触发权限申请弹窗。需检查canRequestPermission
接口确认是否可重新申请。若用户勾选“不再询问”,需引导用户在系统设置中手动开启权限。
在HarmonyOS Next中,当用户拒绝动态权限申请后,系统会记录拒绝状态,默认不会再次自动弹窗。可以通过以下方式处理:
- 在用户拒绝后,通过UI提示引导用户手动开启权限(例如设置页入口)。
- 使用
abilityAccessCtrl
的verifyAccessToken
方法检查权限状态,若未授予则展示自定义解释说明。 - 通过
settings
模块的openSecuritySettings
方法跳转到权限管理页面,由用户手动开启。
注意:需合理设计交互逻辑,避免频繁打扰用户,遵循最小必要原则。