1# 授权持久化
2
3## 场景介绍
4
5应用通过Picker获取临时授权,临时授权在应用退出后或者设备重启后会清除,如果应用重启或者设备重启后需要直接访问之前已访问过的文件,则对文件进行持久化授权。
6
7## 通过Picker获取临时授权并进行授权持久化
8
9通过Picker选择文件或文件夹进行临时授权,然后应用可以按需通过文件分享接口([ohos.fileshare](../reference/apis-core-file-kit/js-apis-fileShare.md))进行持久化授权。
10
111. 应用仅临时需要访问公共目录的数据,例如:通讯类应用需要发送用户的文件或者图片。应用调用Picker的([select](../reference/apis-core-file-kit/js-apis-file-picker.md#select-3))接口选择需要发送的文件或者图片,此时应用获取到是该文件的临时访问权限,应用重启或者设备重启后,再次访问该文件则仍需使用Picker进行文件选择。
12
132. 应用如果需要长期访问某个文件或目录时,可以通过Picker选择文件或文件夹进行临时授权,然后利用persistPermission接口([ohos.fileshare.persistPermission](../reference/apis-core-file-kit/js-apis-fileShare.md#filesharepersistpermission11))对授权进行持久化(在授权方同意被持久化的情况下),例如:文档编辑类应用本次编辑完一个用户文件,期望在历史记录中可以直接选中打开,无需再拉起Picker进行选择授权。
14
15可使用canIUse接口,确认设备是否具有以下系统能力:SystemCapability.FileManagement.AppFileService.FolderAuthorization16
17```ts
18if (!canIUse('SystemCapability.FileManagement.AppFileService.FolderAuthorization')) {
19    console.error('this api is not supported on this device');
20    return;
21}
22```
23
24**需要权限**
25ohos.permission.FILE_ACCESS_PERSIST,具体参考[访问控制-申请应用权限](../security/AccessToken/determine-application-mode.md)。
26
27**示例:**
28
29```ts
30import { BusinessError } from '@kit.BasicServicesKit';
31import { picker } from '@kit.CoreFileKit';
32import { fileShare } from '@kit.CoreFileKit';
33
34async function persistPermissionExample() {
35    try {
36        let DocumentSelectOptions = new picker.DocumentSelectOptions();
37        let documentPicker = new picker.DocumentViewPicker();
38        let uris = await documentPicker.select(DocumentSelectOptions);
39        let policyInfo: fileShare.PolicyInfo = {
40            uri: uris[0],
41            operationMode: fileShare.OperationMode.READ_MODE,
42        };
43        let policies: Array<fileShare.PolicyInfo> = [policyInfo];
44        fileShare.persistPermission(policies).then(() => {
45            console.info("persistPermission successfully");
46        }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
47            console.error("persistPermission failed with error message: " + err.message + ", error code: " + err.code);
48            if (err.code == 13900001 && err.data) {
49                for (let i = 0; i < err.data.length; i++) {
50                    console.error("error code : " + JSON.stringify(err.data[i].code));
51                    console.error("error uri : " + JSON.stringify(err.data[i].uri));
52                    console.error("error reason : " + JSON.stringify(err.data[i].message));
53                }
54            }
55        });
56    } catch (error) {
57        let err: BusinessError = error as BusinessError;
58        console.error('persistPermission failed with err: ' + JSON.stringify(err));
59    }
60}
61```
62
63**注意**
64> **1**、持久化授权文件信息建议应用在本地存储数据,供后续按需激活持久化文件。
65> <br>**2**、持久化授权的数据存储在系统的数据库中,应用或者设备重启后需要激活已持久化的授权才可以正常使用[激活持久化授权](#激活已经持久化的权限访问文件或目录)。
66> <br>**3**、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
67> <br>**4**、应用在卸载时会将之前的授权数据全部清除,重新安装后需要重新授权。
68
69**备注**
70> C/C++持久化授权接口说明及开发指南具体参考:[OH_FileShare_PersistPermission持久化授权接口](native-fileshare-guidelines.md)。
71
723.可以通过revokePermission接口([ohos.fileshare.revokePermission](../reference/apis-core-file-kit/js-apis-fileShare.md#filesharerevokepermission11))对已持久化的文件取消授权,同时更新应用存储的数据以删除最近访问数据。
73
74**需要权限**
75ohos.permission.FILE_ACCESS_PERSIST,具体参考[访问控制-申请应用权限](../security/AccessToken/determine-application-mode.md)。
76
77**示例:**
78
79```ts
80import { BusinessError } from '@kit.BasicServicesKit';
81import { picker } from '@kit.CoreFileKit';
82import { fileShare } from '@kit.CoreFileKit';
83
84async function revokePermissionExample() {
85    try {
86        let uri = "file://docs/storage/Users/username/tmp.txt";
87        let policyInfo: fileShare.PolicyInfo = {
88            uri: uri,
89            operationMode: fileShare.OperationMode.READ_MODE,
90        };
91        let policies: Array<fileShare.PolicyInfo> = [policyInfo];
92        fileShare.revokePermission(policies).then(() => {
93            console.info("revokePermission successfully");
94        }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
95            console.error("revokePermission failed with error message: " + err.message + ", error code: " + err.code);
96            if (err.code == 13900001 && err.data) {
97                for (let i = 0; i < err.data.length; i++) {
98                    console.error("error code : " + JSON.stringify(err.data[i].code));
99                    console.error("error uri : " + JSON.stringify(err.data[i].uri));
100                    console.error("error reason : " + JSON.stringify(err.data[i].message));
101                }
102            }
103        });
104    } catch (error) {
105        let err: BusinessError = error as BusinessError;
106        console.error('revokePermission failed with err: ' + JSON.stringify(err));
107    }
108}
109```
110
111**注意**
112> **1**、示例中的uri来源自应用存储的持久化数据中。
113> <br>**2**、建议按照使用需求去激活对应的持久化权限,不要盲目的全量激活。
114> <br>**3**、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
115
116**备注**
117> C/C++去持久化授权接口说明及开发指南具体参考:[OH_FileShare_RevokePermission去持久化授权接口](native-fileshare-guidelines.md)。
118
119## 激活已经持久化的权限访问文件或目录
120
121对于应用已经持久化的授权,应用每次启动时实际未加载到内存中,需要应用按需进行手动激活已持久化授权的权限,通过activatePermission接口([ohos.fileshare.activatePermission](../reference/apis-core-file-kit/js-apis-fileShare.md#fileshareactivatepermission11))对已经持久化授权的权限进行使能操作,否则已经持久化授权的权限仍存在不能使用的情况。
122
123**需要权限**
124ohos.permission.FILE_ACCESS_PERSIST,具体参考[访问控制-申请应用权限](../security/AccessToken/determine-application-mode.md)。
125
126**示例:**
127
128```ts
129import { BusinessError } from '@kit.BasicServicesKit';
130import { picker } from '@kit.CoreFileKit';
131import { fileShare } from '@kit.CoreFileKit';
132
133async function activatePermissionExample() {
134    try {
135        let uri = "file://docs/storage/Users/username/tmp.txt";
136        let policyInfo: fileShare.PolicyInfo = {
137            uri: uri,
138            operationMode: fileShare.OperationMode.READ_MODE,
139        };
140        let policies: Array<fileShare.PolicyInfo> = [policyInfo];
141        fileShare.activatePermission(policies).then(() => {
142            console.info("activatePermission successfully");
143        }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
144            console.error("activatePermission failed with error message: " + err.message + ", error code: " + err.code);
145            if (err.code == 13900001 && err.data) {
146                for (let i = 0; i < err.data.length; i++) {
147                    console.error("error code : " + JSON.stringify(err.data[i].code));
148                    console.error("error uri : " + JSON.stringify(err.data[i].uri));
149                    console.error("error reason : " + JSON.stringify(err.data[i].message));
150                    if (err.data[i].code == fileShare.PolicyErrorCode.PERMISSION_NOT_PERSISTED) {
151                        //可以选择进行持久化后再激活。
152                    }
153                }
154            }
155        });
156    } catch (error) {
157        let err: BusinessError = error as BusinessError;
158        console.error('activatePermission failed with err: ' + JSON.stringify(err));
159    }
160}
161```
162
163> **注意**
164> 1、示例中的uri来源自应用存储的持久化数据中。
165> 2、建议按照使用需求去激活对应的持久化权限,不要盲目的全量激活。
166> 3、如果激活失败显示未持久化的权限可以按照示例进行持久化。
167> 4、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
168
169C/C++持久化授权激活接口说明及开发指南具体参考:[OH_FileShare_ActivatePermission持久化授权激活接口](native-fileshare-guidelines.md)。
170