第95篇 | HarmonyOS 权限与隐私声明:从代码反推用户要看到的说明

权限声明不能靠感觉写。双镜记忆相机用到了相机、定位、生物认证、网络、握姿感知、隐私防窥等能力,每一个权限都应该能在代码里找到使用场景,也应该能在用户文案里解释清楚。

这一篇从 module.json5 的 requestPermissions 开始,反推页面里什么时候申请权限、拒绝后如何降级、用户为什么要授权。发布和社区文章里讲权限时,最好能做到“权限名、触发时机、用户价值、拒绝后表现”四列对齐。

本篇目标

  • 从配置文件列出应用声明的所有权限。
  • 把权限声明和页面触发函数对应起来。
  • 确认拒绝权限后仍有可解释的降级路径。
  • 整理隐私声明,说明照片、定位、Key、保险箱分别如何使用。

对应源码位置

  • superImage/entry/src/main/module.json5
  • superImage/entry/src/main/ets/pages/Index.ets

权限清单要从配置开始

requestPermissions 是最直观的权限清单。这里能看到 CAMERA、ACCESS_BIOMETRIC、INTERNET、GET_NETWORK_INFO、LOCATION、DETECT_GESTURE、DLP_GET_HIDE_STATUS 等能力。

写隐私声明时不要只写“我们会使用必要权限”,而是逐条解释:相机用于双摄拍摄,定位用于地图记忆和旧地提醒,生物认证用于保险箱,网络用于在线 ARK 能力。

权限声明需要和源码触发点、用户可见说明一一对应

权限声明需要和源码触发点、用户可见说明一一对应

    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:camera_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.ACCESS_BIOMETRIC",
        "reason": "$string:biometric_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.INTERNET",
        "reason": "$string:network_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.APPROXIMATELY_LOCATION",
        "reason": "$string:location_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "$string:location_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.DETECT_GESTURE",
        "reason": "$string:gesture_permission_reason",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": "ohos.permission.DLP_GET_HIDE_STATUS",
        "reason": "$string:dlp_antipeep_permission_reason",
        "usedScene": {
          "abilities": [

页面里保留权限分组

Index 页面把相机、生物认证、定位、握姿权限分别放到独立数组或函数里。这比在业务代码里散写字符串更清楚,也方便后续做权限说明表。

如果后续新增通知、相册保存、蓝牙或传感器权限,也建议沿用这种分组方式,把权限名和业务场景绑定。

权限分组字段让声明、申请和说明更容易对应

权限分组字段让声明、申请和说明更容易对应

  private readonly cameraPermissionList: Array<Permissions> = ['ohos.permission.CAMERA'];
  private readonly biometricPermissionList: Array<Permissions> = ['ohos.permission.ACCESS_BIOMETRIC'];
  private readonly locationPermissionList: Array<Permissions> = [
    'ohos.permission.APPROXIMATELY_LOCATION',
    'ohos.permission.LOCATION'
  ];
  private readonly gesturePermissionList: Array<Permissions> = ['ohos.permission.DETECT_GESTURE'];

定位权限要区分粗略和精确

定位权限里同时有 APPROXIMATELY_LOCATION 和 LOCATION。项目先检查粗略和精确权限,再决定还需要请求哪些。这样做比一次性请求所有权限更可解释。

用户拒绝定位后,相机主流程仍应可用,只是地图记忆、附近回忆、去年今日等能力会降级。隐私说明里要把这个差异写清楚。

定位权限要区分粗略和精确,并保留拒绝后的业务降级

定位权限要区分粗略和精确,并保留拒绝后的业务降级

  private async requestLocationPermissions(): Promise<boolean> {
    const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    const hostContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
    try {
      let approximateGranted = await this.checkLocationPermissionGrant('ohos.permission.APPROXIMATELY_LOCATION') ===
        abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
      let preciseGranted = await this.checkLocationPermissionGrant('ohos.permission.LOCATION') ===
        abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;

      let pendingPermissions: Array<Permissions> = [];
      if (!approximateGranted && !preciseGranted) {
        pendingPermissions = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];
      } else if (approximateGranted && !preciseGranted) {
        pendingPermissions = ['ohos.permission.LOCATION'];
      }

      if (pendingPermissions.length > 0) {
        const result: PermissionRequestResult = await atManager.requestPermissionsFromUser(hostContext, pendingPermissions);
        for (let index = 0; index < result.authResults.length; index++) {
          const granted = result.authResults[index] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
          const permissionName = pendingPermissions[index];
          if (permissionName === 'ohos.permission.APPROXIMATELY_LOCATION' && granted) {
            approximateGranted = true;
          }
          if (permissionName === 'ohos.permission.LOCATION' && granted) {
            preciseGranted = true;
            approximateGranted = true;
          }
        }
      }

      this.locationPermissionReady = approximateGranted || preciseGranted;
      this.preciseLocationReady = preciseGranted;
      if (this.locationPermissionReady && !this.preciseLocationReady) {
        this.currentLocationStatus = '当前为模糊定位,回忆点位可能有偏差。';
      }
      console.info(`[LocationTrace] permissions approximate=${approximateGranted} precise=${preciseGranted}`);
      return this.locationPermissionReady;
    } catch (error) {
      const err = error as BusinessError;

相机和生物认证要有拒绝路径

相机权限是拍摄入口,生物认证是保险箱入口。两者都要在用户操作时申请,并在拒绝后给出明确状态,而不是让按钮静默失效。

保险箱尤其要注意:权限未授予或认证失败时,不能泄露私密内容;页面应该保留锁定状态,并说明需要认证后查看。

相机和生物认证权限都要有拒绝后的用户可见状态

相机和生物认证权限都要有拒绝后的用户可见状态

建议把隐私说明整理成表格:权限、触发按钮、使用数据、是否上传、拒绝后表现。这个表可以直接服务发布材料和社区问答。

工程验收表

检查项 通过标准
权限全集 module.json5 里的每个权限都能找到业务用途。
触发时机 权限在用户触发相关能力时申请,不提前打扰。
拒绝路径 拒绝后页面给出明确文案和可用降级能力。
隐私说明 照片、定位、Key、保险箱的使用边界写清楚。

真机复测口令

module.json5 的权限逐条映射到用户动作:相机对应拍摄,定位对应地图记忆,生物认证对应保险箱,网络对应在线 ARK 能力,传感器对应握姿或空间感知。每个权限都要能说清“什么时候申请、为什么申请、拒绝后怎么降级”。

复测时至少拒绝一次相机权限、定位权限和生物认证。拒绝后页面不能静默失败,也不能绕过隐私边界。尤其是保险箱,认证失败时必须停留在锁定态,不能为了展示效果提前渲染私密记录。

今日练习

  1. 为每个权限补一行“触发按钮、使用数据、拒绝后表现”。
  2. 拒绝相机权限后再点拍摄,检查状态文案是否明确。
  3. 拒绝生物认证后进入保险箱,确认私密内容仍不可见。
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐