授权持久化
=====

#### 场景介绍

应用可以通过Picker[选择文件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/select-user-file)或[保存文件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/save-user-file)获取到临时授权，临时授权在应用退出后或者设备重启后会清除。如果应用重启或者设备重启后需要直接访问之前已访问过的文件，则需要对文件进行持久化授权。

#### 通过Picker获取临时授权并进行授权持久化

通过Picker选择文件或文件夹进行临时授权，该方式获取到的URI只具有**临时读写权限**。应用后续可按需通过文件分享接口（[ohos.fileshare](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-fileshare)）进行持久化授权。

1.应用仅临时需要访问公共目录的数据，例如：通讯类应用需要发送用户的文件或者图片。应用调用Picker的([select](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-picker#select-3))接口选择需要发送的文件或者图片，此时应用获取到是该文件的临时访问权限，应用重启或者设备重启后，再次访问该文件则仍需使用Picker进行文件选择。

2.应用如果需要长期访问某个文件或目录时，可以通过Picker选择文件或文件夹进行临时授权，然后利用persistPermission接口（[ohos.fileshare.persistPermission](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-fileshare#filesharepersistpermission11)）对授权进行持久化（在授权方同意被持久化的情况下，例如使用Picker选择文件场景，Picker会将权限授予当前应用，即可进行授权持久化），例如：文档编辑类应用本次编辑完一个用户文件，期望在历史记录中可以直接选中打开，无需再拉起Picker进行选择授权。

可使用canIUse接口，确认设备是否具有以下系统能力：SystemCapability.FileManagement.AppFileService.FolderAuthorization。

if (!canIUse('SystemCapability.FileManagement.AppFileService.FolderAuthorization')) {
    console.error('this api is not supported on this device');
    return;
}

**需要权限**

ohos.permission.FILE\_ACCESS\_PERSIST，具体参考[访问控制-申请应用权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/determine-application-mode)。

**示例：**

import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';

export async function persistPermissionExample() {
  try {
    // ...
    let documentSelectOptions = new picker.DocumentSelectOptions();
    let documentPicker = new picker.DocumentViewPicker();
    let uris = await documentPicker.select(documentSelectOptions);
    // 可以组合授予多个权限，例如读写权限可使用 fileShare.OperationMode.READ\_MODE | fileShare.OperationMode.WRITE\_MODE。
    // 注意：只能对已获取到的临时权限进行持久化授权操作，否则会报错。
    let policyInfo: fileShare.PolicyInfo = {
      uri: uris\[0\],
      operationMode: fileShare.OperationMode.READ\_MODE,
    };
    let policies: fileShare.PolicyInfo\[\] = \[policyInfo\];
    fileShare.persistPermission(policies).then(() => {
      console.info('persistPermission successfully');
    }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
      console.error('persistPermission failed with error message: ' + err.message + ', error code: ' + err.code);
      if (err.code == 13900001 && err.data) {
        for (let i = 0; i < err.data.length; i++) {
          console.error('error code : ' + JSON.stringify(err.data\[i\].code));
          console.error('error uri : ' + JSON.stringify(err.data\[i\].uri));
          console.error('error reason : ' + JSON.stringify(err.data\[i\].message));
        }
      }
    });
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error(\`persistPermission failed with err, Error code: ${err.code}, message: ${err.message}\`);
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/8b/v3/ImEw5l5-TSK6va1TaHz4Zg/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073338Z&HW-CC-Expire=86400&HW-CC-Sign=A02D9CDBF6D1FAB0C3AF8E2EE9F3D421FDE9AAD8A852CA7D3ECB1FAAC86E481D)

1.  持久化授权文件信息建议应用在本地存储数据，供后续按需激活持久化文件。
2.  持久化授权的数据存储在系统的数据库中，应用或者设备重启后需要激活已持久化的授权才可以正常使用[激活持久化授权](#激活已经持久化的权限访问文件或目录)。
3.  持久化权限接口(可以使用canIUse接口进行校验能力是否可用)，且需要申请对应的权限。
4.  应用在卸载时会将之前的授权数据全部清除，重新安装后需要重新授权。
5.  只能对已获取到的临时权限进行持久化授权操作，否则会报错。

**备注**：C/C++持久化授权接口说明及开发指南具体参考：[OH\_FileShare\_PersistPermission持久化授权接口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/native-fileshare-guidelines)。

3.可以通过revokePermission接口（[ohos.fileshare.revokePermission](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-fileshare#filesharerevokepermission11)）对已持久化的文件取消授权，同时更新应用存储的数据以删除最近访问数据。

**需要权限**

ohos.permission.FILE\_ACCESS\_PERSIST，具体参考[访问控制-申请应用权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/determine-application-mode)。

**示例：**

import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';

// ...
export async function revokePermissionExample() {
  try {
    let uri = 'file://docs/storage/Users/username/tmp.txt';
    // 可以组合取消多个权限，例如读写权限可使用 fileShare.OperationMode.READ\_MODE | fileShare.OperationMode.WRITE\_MODE。
    // 注意：只能对已获取到的持久化权限进行取消持久化授权操作，否则会报错。
    let policyInfo: fileShare.PolicyInfo = {
      uri: uri,
      operationMode: fileShare.OperationMode.READ\_MODE,
    };
    let policies: fileShare.PolicyInfo\[\] = \[policyInfo\];
    fileShare.revokePermission(policies).then(() => {
      console.info('revokePermission successfully');
    }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
      console.error('revokePermission failed with error message: ' + err.message + ', error code: ' + err.code);
      if (err.code == 13900001 && err.data) {
        for (let i = 0; i < err.data.length; i++) {
          console.error('error code : ' + JSON.stringify(err.data\[i\].code));
          console.error('error uri : ' + JSON.stringify(err.data\[i\].uri));
          console.error('error reason : ' + JSON.stringify(err.data\[i\].message));
        }
      }
    });
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error(\`revokePermission failed with err, Error code: ${err.code}, message: ${err.message}\`);
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/23/v3/abmuA6JlTNqKWfdqVWTxIw/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073338Z&HW-CC-Expire=86400&HW-CC-Sign=8817F50D165D92B42EDF69161729B2B2421F1064865B7B45291D737599FA9603)

1.  示例中的URI来源自应用存储的持久化数据中。
2.  只能对已获取到的持久化权限进行取消持久化授权操作，建议按照使用需求去取消对应的持久化权限。
3.  持久化权限接口(可以使用canIUse接口进行校验能力是否可用)，且需要申请对应的权限。

**备注**：C/C++去持久化授权接口说明及开发指南具体参考：[OH\_FileShare\_RevokePermission去持久化授权接口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/native-fileshare-guidelines)。

#### 激活已经持久化的权限访问文件或目录

对于应用已经持久化的授权，应用每次启动时实际未加载到内存中，需要应用按需进行手动激活已持久化授权的权限，通过activatePermission接口（[ohos.fileshare.activatePermission](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-fileshare#fileshareactivatepermission11)）对已经持久化授权的权限进行使能操作，否则已经持久化授权的权限仍存在不能使用的情况。

**需要权限**

ohos.permission.FILE\_ACCESS\_PERSIST，具体参考[访问控制-申请应用权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/determine-application-mode)。

**示例：**

import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';

// ...
export async function activatePermissionExample() {
  try {
    let uri = 'file://docs/storage/Users/username/tmp.txt';
    // 可以组合激活多个权限，例如读写权限可使用 fileShare.OperationMode.READ\_MODE | fileShare.OperationMode.WRITE\_MODE。
    // 注意：只能对已获取到的持久化权限进行激活持久化授权操作，否则会报错。
    let policyInfo: fileShare.PolicyInfo = {
      uri: uri,
      operationMode: fileShare.OperationMode.READ\_MODE,
    };
    let policies: fileShare.PolicyInfo\[\] = \[policyInfo\];
    fileShare.activatePermission(policies).then(() => {
      console.info('activatePermission successfully');
    }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
      console.error('activatePermission failed with error message: ' + err.message + ', error code: ' + err.code);
      if (err.code == 13900001 && err.data) {
        for (let i = 0; i < err.data.length; i++) {
          console.error('error code : ' + JSON.stringify(err.data\[i\].code));
          console.error('error uri : ' + JSON.stringify(err.data\[i\].uri));
          console.error('error reason : ' + JSON.stringify(err.data\[i\].message));
          if (err.data\[i\].code == fileShare.PolicyErrorCode.PERMISSION\_NOT\_PERSISTED) {
          // 可以选择进行持久化后再激活。
          }
        }
      }
    });
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error(\`activatePermission failed with err, Error code: ${err.code}, message: ${err.message}\`);
  }
}

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b3/v3/wYKFQBaOS5Kq9RlDOi46OQ/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073338Z&HW-CC-Expire=86400&HW-CC-Sign=1E7CDB4EFDD2CDF48A5690328C67DCF5FFC4E7867FAB21D8CFA1246DE290777D)

1.  示例中的URI来源自应用存储的持久化数据中。
2.  建议按照使用需求去激活对应的持久化权限，不要盲目的全量激活。
3.  如果激活失败显示未持久化的权限可以按照示例进行持久化。
4.  持久化权限接口可以使用canIUse接口进行校验能力是否可用，且需要申请对应的权限。

**备注**：C/C++持久化授权激活接口说明及开发指南具体参考：[OH\_FileShare\_ActivatePermission持久化授权激活接口](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/native-fileshare-guidelines)。

#### 持久化权限保留配置

从API version 24开始，系统新增支持持久化权限保留能力。应用卸载时根据ohos.fileshare.supportPreservePersistentPermission标签保留持久化。再次安装时恢复上次已保留的持久化权限。

#### \[h2\]配置方式

开发者可在应用模块级配置文件[src/main/module.json5](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file)的module标签中metadata里配置ohos.fileshare.supportPreservePersistentPermission标签，以启用持久化权限保留能力。

**metadata标签配置示例**

{
  "module": {
    // ...
    "metadata": \[
      {
        "name": "ohos.fileshare.supportPreservePersistentPermission"
      }
    \],
    // ...
  }
}

**ohos.fileshare.supportPreservePersistentPermission标签说明**

| 属性名称 | 含义 | 数据类型 | 是否可缺省 |
| :-- | :-- | :-- | :-- |
| name | 标识元信息名称，固定值为ohos.fileshare.supportPreservePersistentPermission。 | 字符串 | 该标签不可缺省。 |