HarmonyOS鸿蒙Next中怎么解决动态申请权限时,用户拒绝后无法再次触发弹窗?

HarmonyOS鸿蒙Next中怎么解决动态申请权限时,用户拒绝后无法再次触发弹窗? 动态申请ACCESS_DISTRIBUTED_NETWORK_STATE权限时,用户拒绝后无法再次触发弹窗,如何处理?

4 回复

您好,可以参考以下解决方案:

【解决方案】

系统不鼓励频繁弹窗打扰用户,如果调用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中,当用户拒绝动态权限申请后,系统会记录拒绝状态,默认不会再次自动弹窗。可以通过以下方式处理:

  1. 在用户拒绝后,通过UI提示引导用户手动开启权限(例如设置页入口)。
  2. 使用abilityAccessCtrlverifyAccessToken方法检查权限状态,若未授予则展示自定义解释说明。
  3. 通过settings模块的openSecuritySettings方法跳转到权限管理页面,由用户手动开启。

注意:需合理设计交互逻辑,避免频繁打扰用户,遵循最小必要原则。

回到顶部