授权持久化
场景介绍
应用通过Picker获取临时授权,临时授权在应用退出后或者设备重启后会清除,如果应用重启或者设备重启后需要直接访问之前已访问过的文件,则对文件进行持久化授权。
通过Picker获取临时授权并进行授权持久化
通过Picker选择文件或文件夹进行临时授权,然后应用可以按需通过文件分享接口( ohos.fileshare )进行持久化授权。
-
应用仅临时需要访问公共目录的数据,例如:通讯类应用需要发送用户的文件或者图片。应用调用picker的( select )接口选择需要发送的文件或者图片,此时应用获取到是该文件的临时访问权限,应用重启或者设备重启后,再次访问该文件则仍需使用picker进行文件选则。
-
应用如果需要长期访问某个文件或目录时,可以通过Picker选择文件或文件夹进行临时授权,然后利用persistPermission接口( ohos.fileshare.persistPermission)对授权进行持久化(在授权方同意被持久化的情况下),例如:文档编辑类应用本次编辑完一个用户文件,期望在历史记录中可以直接选中打开,无需再拉起picker进行选择授权。
可使用canIUse接口,确认设备是否具有以下系统能力:SystemCapability.FileManagement.File.Environment.FolderObtain。
if (!canIUse('SystemCapability.FileManagement.File.Environment.FolderObtain')) {
console.error('this api is not supported on this device');
return;
}
需要权限
:ohos.permission.FILE_ACCESS_PERSIST,具体参考 访问控制-申请应用权限 ,该权限APL等级为system_basic,APL等级为normal的应用需要通过ACL的方式跨级别申请。
示例:
import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';
async function persistPermissionExample() {
try {
let DocumentSelectOptions = new picker.DocumentSelectOptions();
let documentPicker = new picker.DocumentViewPicker();
let uris = await documentPicker.select(DocumentSelectOptions);
let policyInfo: fileShare.PolicyInfo = {
uri: uris[0],
operationMode: fileShare.OperationMode.READ_MODE,
};
let policies: Array<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: ' + JSON.stringify(err));
}
}
注意
1、持久化授权文件信息建议应用在本地存储数据,供后续按需激活持久化文件。
2、持久化授权的数据存储在系统的数据库中,应用或者设备重启后需要激活已持久化的授权才可以正常使用 激活持久化授权。
3、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
4、应用在卸载时会将之前的授权数据全部清除,重新安装后需要重新授权。
备注
C/C++持久化授权接口说明及开发指南具体参考: OH_FileShare_PersistPermission持久化授权接口。
3.可以通过revokePermission接口(ohos.fileshare.revokePermission)对已持久化的文件取消授权,同时更新应用存储的数据以删除最近访问数据。
需要权限
:ohos.permission.FILE_ACCESS_PERSIST,具体参考访问控制-申请应用权限,该权限APL等级为system_basic,APL等级为normal的应用需要通过ACL的方式跨级别申请。
示例:
import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';
async function revokePermissionExample() {
try {
let uri = "file://docs/storage/Users/username/tmp.txt";
let policyInfo: fileShare.PolicyInfo = {
uri: uri,
operationMode: fileShare.OperationMode.READ_MODE,
};
let policies: Array<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: ' + JSON.stringify(err));
}
}
注意
1、示例中的uri来源自应用存储的持久化数据中。
2、建议按照使用需求去激活对应的持久化权限,不要盲目的全量激活。
3、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
激活已经持久化的权限访问文件或目录
对于应用已经持久化的授权,应用每次启动时实际未加载到内存中,需要应用按需进行手动激活已持久化授权的权限,通过activatePermission接口(ohos.fileshare.activatePermission)对已经持久化授权的权限进行使能操作,否则已经持久化授权的权限仍存在不能使用的情况。
需要权限
:ohos.permission.FILE_ACCESS_PERSIST,具体参考访问控制-申请应用权限,该权限APL等级为system_basic,APL等级为normal的应用需要通过ACL的方式跨级别申请。
示例:
import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import { fileShare } from '@kit.CoreFileKit';
async function activatePermissionExample() {
try {
let uri = "file://docs/storage/Users/username/tmp.txt";
let policyInfo: fileShare.PolicyInfo = {
uri: uri,
operationMode: fileShare.OperationMode.READ_MODE,
};
let policies: Array<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: ' + JSON.stringify(err));
}
}
注意
1、示例中的uri来源自应用存储的持久化数据中。
2、建议按照使用需求去激活对应的持久化权限,不要盲目的全量激活。
3、如果激活失败显示未持久化的权限可以按照示例进行持久化。
4、持久化权限接口(仅在2in1上生效可以使用canIUse接口进行校验能力是否可用),且需要申请对应的权限。
授权持久化(C/C++)
场景介绍
应用通过Picker获取临时授权,临时授权在应用退出后或者设备重启后会清除,如果应用重启或者设备重启后需要直接访问之前已访问过的文件,则对文件进行 持久化授权 。FileShare提供了支持基于URI的文件及目录授于持久化权限、权限激活、权限查询等方法。
接口说明
接口的详细介绍请参见 API参考 。
接口名称 | 描述 |
---|---|
OH_FileShare_PersistPermission(const FileShare_PolicyInfo *policies, unsigned int policyNum, FileShare_PolicyErrorResult **result, unsigned int *resultNum) | 对所选择的多个文件或目录URI持久化授权 |
OH_FileShare_RevokePermission(const FileShare_PolicyInfo *policies, unsigned int policyNum, FileShare_PolicyErrorResult **result, unsigned int *resultNum) | 对所选择的多个文件或目录URI取消持久化授权 |
OH_FileShare_ActivatePermission(const FileShare_PolicyInfo *policies, unsigned int policyNum, FileShare_PolicyErrorResult **result, unsigned int *resultNum) | 使能多个已经永久授权过的文件或目录URI |
OH_FileShare_DeactivatePermission(const FileShare_PolicyInfo *policies, unsigned int policyNum, FileShare_PolicyErrorResult **result, unsigned int *resultNum) | 取消使能授权过的多个文件或目录URI |
OH_FileShare_CheckPersistentPermission(const FileShare_PolicyInfo *policies, unsigned int policyNum, bool **result, unsigned int *resultNum) | 校验所选择的多个文件或目录URI的持久化权限结果 |
OH_FileShare_ReleasePolicyErrorResult(FileShare_PolicyErrorResult *errorResult, unsigned int resultNum) | 释放FileShare_PolicyErrorResult内存 |
约束与限制
-
使用文件分享的相关接口,需确认设备具有以下系统能力:SystemCapability.FileManagement.AppFileService.FolderAuthorization。
-
在调用文件分享的相关接口前,需要申请权限:“ohos.permission.FILE_ACCESS_PERSIST”,申请方式请参考 访问控制-申请应用权限 。
开发步骤
以下步骤描述了如何使用FileShare提供的Native API接口
添加动态链接库
CMakeLists.txt中添加以下lib。
target_link_libraries(sample PUBLIC libohfileshare.so)
头文件
#include <filemanagement/fileshare/oh_file_share.h>
#include <iostream>
- 创建FileShare_PolicyInfo实例,调用OH_FileShare_PersistPermission接口,设置URI的持久化授权,接口入参policyNum最大上限为500。
static const uint32_t POLICY_NUM = 2;
char strTestPath1[] = "file://com.example.fileshare/data/storage/el2/base/files/test1.txt";
char strTestPath2[] = "file://com.example.fileshare/data/storage/el2/base/files/test2.txt";
FileShare_PolicyInfo policy[POLICY_NUM] = {
{strTestPath1, static_cast<unsigned int>(strlen(strTestPath1)), FileShare_OperationMode::READ_MODE},
{strTestPath2, static_cast<unsigned int>(strlen(strTestPath2)), FileShare_OperationMode::WRITE_MODE}};
FileShare_PolicyErrorResult* result = nullptr;
uint32_t resultNum = 0;
auto ret = OH_FileShare_PersistPermission(policy, POLICY_NUM, &result, &resultNum);
if (ret != ERR_OK) {
if (ret == ERR_EPERM && result != nullptr) {
for(uint32_t i = 0; i < resultNum; i++) {
std::cout << "error uri: " << result[i].uri << std::endl;
std::cout << "error code: " << result[i].code << std::endl;
std::cout << "error message: " << result[i].message << std::endl;
}
}
}
OH_FileShare_ReleasePolicyErrorResult(result, resultNum);
- 调用OH_FileShare_ActivatePermission接口,激活启用已授权过的URI,接口入参policyNum最大上限为500。
auto ret = OH_FileShare_ActivatePermission(policy, POLICY_NUM, &result, &resultNum);
if (ret != ERR_OK) {
if (ret == ERR_EPERM && result != nullptr) {
for(uint32_t i = 0; i < resultNum; i++) {
std::cout << "error uri: " << result[i].uri << std::endl;
std::cout << "error code: " << result[i].code << std::endl;
std::cout << "error message: " << result[i].message << std::endl;
}
}
}
OH_FileShare_ReleasePolicyErrorResult(result, resultNum);
- 调用OH_FileShare_DeactivatePermission接口,停止已启用授权过URI的访问权限,接口入参policyNum最大上限为500。
auto ret = OH_FileShare_DeactivatePermission(policy, POLICY_NUM, &result, &resultNum);
if (ret != ERR_OK) {
if (ret == ERR_EPERM && result != nullptr) {
for(uint32_t i = 0; i < resultNum; i++) {
std::cout << "error uri: " << result[i].uri << std::endl;
std::cout << "error code: " << result[i].code << std::endl;
std::cout << "error message: " << result[i].message << std::endl;
}
}
}
OH_FileShare_ReleasePolicyErrorResult(result, resultNum);
- 调用OH_FileShare_RevokePermission接口,撤销已经授权的URI持久化权限,接口入参policyNum最大上限为500。
auto ret = OH_FileShare_RevokePermission(policy, POLICY_NUM, &result, &resultNum);
if (ret != ERR_OK) {
if (ret == ERR_EPERM && result != nullptr) {
for(uint32_t i = 0; i < resultNum; i++) {
std::cout << "error uri: " << result[i].uri << std::endl;
std::cout << "error code: " << result[i].code << std::endl;
std::cout << "error message: " << result[i].message << std::endl;
}
}
}
OH_FileShare_ReleasePolicyErrorResult(result, resultNum);
- 调用OH_FileShare_CheckPersistentPermission接口,检查URI持久化权限,接口入参policyNum最大上限为500。
bool *result = nullptr;
auto ret = OH_FileShare_CheckPersistentPermission(policy, POLICY_NUM, &result, &resultNum);
if (result != nullptr && resultNum > 0) {
for(uint32_t i = 0; i < resultNum && resultNum <= POLICY_NUM; i++) {
std::cout << "uri: " << policy[i].uri << std::endl;
std::cout << "result: " << result[i] << std::endl;
}
}
std::cout << "retCode: " << ret << std::endl;
free(result);
鸿蒙全栈开发全新学习指南
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档用来跟着学习是非常有必要的。
针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
本路线共分为四个阶段:
第一阶段:鸿蒙初中级开发必备技能
第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH
第三阶段:应用开发中高级就业技术
第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH
《鸿蒙 (Harmony OS)开发学习手册》(共计892页)
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
开发基础知识:gitee.com/MNxiaona/733GH
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……
基于ArkTS 开发
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……
鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH
鸿蒙入门教学视频:
美团APP实战开发教学:gitee.com/MNxiaona/733GH
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:
gitee.com/MNxiaona/733GH