HarmonyOS鸿蒙Next应用如何处理拒绝权限二次申请授权?请提供源码和步骤讲解

HarmonyOS鸿蒙Next应用如何处理拒绝权限二次申请授权?请提供源码和步骤讲解 在鸿蒙系统中,对于用户权限的申请,会有三种用户选择方式:

  1. 单次使用允许
  2. 使用应用期间(长时)允许
  3. 不允许

当用户选择不允许后,再次向用户申请权限,该系统申请权限弹框就不会再显示。因为鸿蒙系统机制规格处理如此,此举是为了避免三方应用频繁申请权限,骚扰用户。

之前的通用方案是,跳转到应用设置界面,让用户自己去手动设置同意所需的权限。但是这样的操作,对于用户来说是跳出,体验并不是很好。

鸿蒙应用如何处理拒绝权限二次申请授权?请提供源码和步骤讲解

3 回复

cke_363.png

一、结论

当应用通过requestPermissionsFromUser()拉起弹框请求用户授权时,用户拒绝授权。应用将无法再次通过该接口申请权限拉起弹框,需要用户在系统应用“设置”的界面中,手动授予权限。

应用此种情况下,可以通过调用requestPermissionOnSetting(),直接拉起权限设置弹框,引导用户授予权限。

atManager.requestPermissionOnSetting(context, ['ohos.permission.APPROXIMATELY_LOCATION']).then((data: Array<abilityAccessCtrl.GrantStatus>) => {
  console.info('data:' + JSON.stringify(data));
}).catch((err: BusinessError) => {
  console.error('data:' + JSON.stringify(err));
});

二、代码实现和详细解释

直接拉起权限设置半模态弹框,引导用户授予权限。

申请ohos.permission.CAMERA权限

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));
});

更多关于HarmonyOS鸿蒙Next应用如何处理拒绝权限二次申请授权?请提供源码和步骤讲解的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,应用需在module.json5中声明权限。当用户拒绝授权后,应用可通过abilityAccessCtrl.createAtManager()创建权限管理对象。使用requestPermissionsFromUser()方法可再次触发授权弹窗。为避免频繁打扰,建议在调用前通过checkAccessToken()检查当前权限状态,仅在未授权时申请。

关键步骤:

  1. module.json5requestPermissions字段配置所需权限。
  2. 在代码中导入@kit.AbilityAccessCtrlKit模块。
  3. 使用AtManagerrequestPermissionsFromUser()方法申请权限。

示例代码片段:

import { abilityAccessCtrl, common } from '@kit.AbilityAccessCtrlKit';
// 创建AtManager实例并调用requestPermissionsFromUser

在HarmonyOS Next中,处理用户拒绝权限后的二次申请,核心是引导用户前往系统设置页手动开启权限。由于系统安全策略限制,应用无法在用户选择“不允许”后再次弹出系统授权弹窗。以下是推荐的实现方案、关键步骤和示例代码。

核心思路

  1. 首次申请权限被拒后,向用户展示友好的解释说明。
  2. 提供明确的入口(如按钮),引导用户跳转到本应用的系统设置详情页。
  3. 在用户可能返回应用的关键时机(如onPageShow),重新检查权限状态。

关键步骤与代码示例

1. 权限声明与动态申请 首先在module.json5文件中声明所需权限,例如相机权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA"
      }
    ]
  }
}

在页面中,使用@ohos.abilityAccessCtrl模块进行动态权限申请。

import { accessCtrl, Permissions } from '@ohos.abilityAccessCtrl';
import { common, Want } from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
import { promptAction } from '@ohos.promptAction';

@Entry
@Component
struct Index {
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

  // 申请权限
  async requestPermission(): Promise<void> {
    let atManager: accessCtrl.AtManager = accessCtrl.createAtManager();
    try {
      // 1. 检查权限状态
      let grantStatus: accessCtrl.GrantStatus = await atManager.checkAccessToken(this.context, Permissions.CAMERA);
      if (grantStatus === accessCtrl.GrantStatus.PERMISSION_GRANTED) {
        promptAction.showToast({ message: '权限已授予' });
        // 执行需要权限的操作...
        return;
      }

      // 2. 权限未授予,发起申请
      let requestResult: accessCtrl.PermissionRequestResult = await atManager.requestPermissionsFromUser(this.context, [Permissions.CAMERA]);
      let grantResults: Array<number> = requestResult.authResults;
      let result: number = grantResults[0];

      // 3. 处理申请结果
      if (result === accessCtrl.GrantStatus.PERMISSION_GRANTED) {
        promptAction.showToast({ message: '用户授权成功' });
        // 执行需要权限的操作...
      } else {
        // 用户拒绝(选择了“不允许”)
        this.showPermissionGuideDialog(); // 展示引导弹窗
      }
    } catch (err) {
      const error: BusinessError = err as BusinessError;
      console.error(`权限申请失败,错误码:${error.code}, 错误信息:${error.message}`);
    }
  }

  // 展示引导用户去设置的弹窗或界面
  showPermissionGuideDialog(): void {
    // 这里应构建一个自定义弹窗(使用CustomDialogController)或界面,向用户解释为什么需要权限,并提供一个“去设置”按钮。
    // 当用户点击“去设置”按钮时,调用下面的 `goToAppSettings` 方法。
    // 示例中省略具体UI构建代码,直接调用跳转。
    this.goToAppSettings();
  }

  // 跳转到本应用的系统设置详情页
  async goToAppSettings(): Promise<void> {
    let wantInfo: Want = {
      action: 'action.settings.app.info',
      parameters: {
        settingsParamBundleName: this.context.abilityInfo.bundleName
      }
    };
    try {
      await this.context.startAbility(wantInfo);
    } catch (err) {
      const error: BusinessError = err as BusinessError;
      console.error(`跳转设置失败,错误码:${error.code}, 错误信息:${error.message}`);
      promptAction.showToast({ message: '无法打开设置,请手动前往系统设置中修改权限' });
    }
  }

  build() {
    Column() {
      Button('申请相机权限')
        .onClick(() => {
          this.requestPermission();
        })
    }
  }
}

2. 监听页面显示并重新检查权限 当用户从系统设置页返回应用时,应在页面显示时重新检查权限状态。

import { Router } from '@ohos.router';

@Entry
@Component
struct Index {
  // ... 省略之前的代码 ...

  // 在页面显示时(例如onPageShow)检查权限
  onPageShow(): void {
    this.checkPermissionStatus();
  }

  async checkPermissionStatus(): Promise<void> {
    let atManager: accessCtrl.AtManager = accessCtrl.createAtManager();
    let grantStatus: accessCtrl.GrantStatus = await atManager.checkAccessToken(this.context, Permissions.CAMERA);
    if (grantStatus === accessCtrl.GrantStatus.PERMISSION_GRANTED) {
      promptAction.showToast({ message: '权限已通过设置开启' });
      // 执行之前被阻止的操作...
    }
    // 如果仍未授权,可以保持引导UI的显示
  }
}

总结: 处理“不允许”后的权限二次申请,标准做法是:

  1. 首次拒绝后:通过自定义UI(非系统弹窗)向用户解释权限必要性,并提供明确的“去设置”按钮
  2. 跳转设置:使用startAbility并指定action.settings.app.infoWant,精准跳转到本应用的系统权限设置页。
  3. 状态同步:在应用从后台返回前台(如onPageShow)时,重新检查权限状态,并更新应用界面和功能。

此方案遵循了HarmonyOS的隐私规范,在尊重用户选择权的同时,提供了清晰的引导路径,是替代反复调用requestPermissionsFromUser的最佳实践。

回到顶部