
访问鸿蒙设备文件 原创
1 通过DevEco Studio访问设备文件
DevEco Studio内置设备文件管理工具Device File Browser,开发者可以在PC端进行文件新建、删除、上传下载等操作,当前支持普通文件视图与应用沙箱视图两种模式,主要使用场景如下:
- 查看设备上的文件列表及基本信息。
- 在设备上搜索文件及文件夹。
- 在设备上新建、删除文件。
- 从PC本地上传文件到设备上,从设备上下载文件到PC本地。
该工具不支持对无权限的目录(如应用沙箱路径)进行增删改,详细操作指导请见访问设备文件。
公共目录/storage/media/100/local/files/Docs支持通过hdc直接上传与下载文件,应用沙箱目录不支持hdc,需通过bftpd命令行访问。
2 通过命令行工具访问应用沙箱
真机设备中内置了bftpd二进制软件,可以通过命令行的方式访问debug应用的沙箱目录。通过该方式可以与编译构建流水线结合,实现批量向应用内推送资源文件等操作。
更多内容请参见命令行方式访问应用沙箱。
3 通过Core File Kit访问和管理设备文件
应用文件包括应用安装文件、应用资源文件、应用缓存文件等,应用文件目录和一部分系统文件(应用运行必须使用的系统文件)组成了一个集合,该集合为应用沙箱目录,代表了应用可见的所有目录范围。
文件分类模型示意:
0900086000300134184.20201216095126.86523331460016843504112994983392.png
系统文件及其目录对于应用是只读的,应用仅能保存文件到应用文件目录下。
对于游戏类应用,需要用过picker组件来访问用户文件、媒体,访问应用文件目录可以通过应用上下文context获取文件路径。
3.1 应用文件访问与管理
开发者可从UIAbilityContext中获取HAP级别的文件路径,或者从ApplicationContext中获取APP级别的文件路径,再通过基础文件操作接口ohos.file.fs实现应用文件访问能力,具体开发指导请参见应用文件访问、ohos.file.fs文件管理API。
3.2 用户文件访问
用户需要分享文件、保存图片、视频等用户文件时,开发者可通过系统预置的文件选择器(FilePicker)实现该能力。通过Picker访问相关文件,将拉起对应的FilePicker应用,引导用户完成界面操作,接口本身无需申请权限。
3.2.1 选择文档/音频类文件
通过文件选择器DocumentViewPicker中的select()接口,拉起FilePicker应用界面进行文件选择。该接口返回的uri权限是临时只读权限,待应用退出后台后,获取的临时权限就会失效。开发者可定义全局变量保存uri,从而对返回结果做集中处理。
文档类uri的格式类型为:
'file://docs/storage/Users/currentUser/<relative_path>/test.txt'
其中各个字段表示的含义为:
uri字段 | 说明 |
file://docs/storage/Users/currentUser/ | 文件管理器的根目录。 |
<relative_path>/ | 文件在根目录下的相对路径。例如:Download/和Documents/。 |
test.txt | 用户文件系统中存储的文件名,支持的文件类型为文件管理器支持的所有类型,以文件管理器为准。例如txt、jpg、mp4和mp3等格式的文件。 |
获取uri后,可通过ohos.file.fs文件管理API对文件进行进一步处理。
3.2.2 选择图片/视频
游戏类应用无法申请相册管理模块读权限'ohos.permission.READ_IMAGEVIDEO',因此需通过PhotoAccessHelper模块的PhotoViewPicker选择本地相册的媒体文件。
媒体文件uri的格式类型为:
图片uri格式:file://media/Photo/[id]/IMG_datetime_0001/displayName.jpg
视频uri格式:file://media/Photo/[id]/VID_datetime_0001/displayName.mp4
音频uri格式:file://media/Audio/[id]/AUD_datetime_0001/displayName.mp3
其中各个字段表示的含义为:
uri字段 | 说明 |
file://media | 表示这个uri是媒体文件。 |
Photo | Photo表示这个uri是媒体文件中的图片或者视频类文件。 |
Audio | 表示这个uri是媒体文件中的音频类文件。 |
[id] | 表示在数据库中多个表中处理后的值,并不是指表中的file_id列,注意请不要使用此id去数据库中查询具体文件。 |
IMG_datetime_0001 | 表示图片文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
VID_datetime_0001 | 表示视频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
AUD_datetime_0001 | 表示音频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。 |
获得媒体uri后使用photoAccessHelper.getAssets接口获取对应uri的PhotoAsset对象。这种方式获取的对象可以调用getThumbnail获取缩略图和使用get接口读取PhotoKeys中的部分信息。
以下为PhotoKeys中支持临时授权方式可以读取的信息:
名称 | 值 | 说明 |
URI | uri | 文件uri。 |
PHOTO_TYPE | media_type | 媒体文件类型。 |
DISPLAY_NAME | display_name | 显示名字。 |
SIZE | size | 文件大小。 |
DATE_ADDED | date_added | 文件创建时的Unix时间戳(单位:秒)。 |
DATE_MODIFIED | date_modified | 文件修改时的Unix时间戳(单位:秒)。修改文件名不会改变此值,当文件内容发生修改时才会更新。 |
DURATION | duration | 持续时间(单位:毫秒)。 |
WIDTH | width | 图片宽度(单位:像素)。 |
HEIGHT | height | 图片高度(单位:像素)。 |
DATE_TAKEN | date_taken | 拍摄时的Unix时间戳(单位:秒)。 |
ORIENTATION | orientation | 图片文件的方向。 |
TITLE | title | 文件标题。 |
下面为通过临时授权方式使用媒体文件uri进行获取缩略图和读取文件部分信息的示例代码:
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { dataSharePredicates } from '@kit.ArkData';
// 定义一个uri数组,用于接收PhotoViewPicker选择图片返回的uri
let uris: Array<string> = [];
const context = getContext(this);
// 调用PhotoViewPicker.select选择图片
async function photoPickerGetUri() {
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
console.info('PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
uris = PhotoSelectResult.photoUris;
}).catch((err: BusinessError) => {
console.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error('PhotoViewPicker failed with err: ' + JSON.stringify(err));
}
}
async function uriGetAssets() {
try {
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
// 配置查询条件,使用PhotoViewPicker选择图片返回的uri进行查询
predicates.equalTo('uri', uris[0]);
let fetchOption: photoAccessHelper.FetchOptions = {
fetchColumns: [photoAccessHelper.PhotoKeys.WIDTH, photoAccessHelper.PhotoKeys.HEIGHT, photoAccessHelper.PhotoKeys.TITLE, photoAccessHelper.PhotoKeys.DURATION],
predicates: predicates
};
let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption);
// 得到uri对应的PhotoAsset对象,读取文件的部分信息
const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
console.info('asset displayName: ', asset.displayName);
console.info('asset uri: ', asset.uri);
console.info('asset photoType: ', asset.photoType);
console.info('asset width: ', asset.get(photoAccessHelper.PhotoKeys.WIDTH));
console.info('asset height: ', asset.get(photoAccessHelper.PhotoKeys.HEIGHT));
console.info('asset title: ' + asset.get(photoAccessHelper.PhotoKeys.TITLE));
// 获取缩略图
asset.getThumbnail((err, pixelMap) => {
if (err === undefined) {
console.info('getThumbnail successful ' + JSON.stringify(pixelMap));
} else {
console.error(`getThumbnail fail with error: ${err.code}, ${err.message}`);
}
});
} catch (error){
console.error('uriGetAssets failed with err: ' + JSON.stringify(error));
}
}
3.2.3 保存用户文件
对音频、图片、视频、文档类文件的保存操作类似,均通过调用对应Picker的save()接口并传入对应的saveOptions来实现。通过Picker访问相关文件,无需申请权限。
当前所有Picker的save接口都是用户可感知的,具体行为是拉起FilePicker, 将文件保存在系统文件管理器管理的特定目录,与图库管理的资源隔离,无法在图库中看到。
对于游戏类应用,若需保存图片、视频资源到图库,需使用相册管理模块的PhotoAccessHelper.showAssetsCreationDialog接口进行保存操作,该接口无需申请系统相册读取权限。
具体开发指导请参见保存用户文件
官方文档参考
原文链接:华为开发者文章
更多问题可关注:
鸿蒙游戏官方网站:已有游戏移植-鸿蒙游戏-华为开发者联盟
公开课:华为开发者学堂
