访问鸿蒙设备文件 原创

游戏技术分享
发布于 2025-5-19 18:09
浏览
0收藏

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​​接口进行保存操作,该接口无需申请系统相册读取权限。

具体开发指导请参见​​保存用户文件​

官方文档参考


原文链接:​​华为开发者文章​


更多问题可关注:

鸿蒙游戏官方网站:​​已有游戏移植-鸿蒙游戏-华为开发者联盟​

公开课:​​华为开发者学堂​

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2025-8-20 19:40:50修改
收藏
回复
举报
回复
    相关推荐