HarmonyOS Next开发学习手册——用户文件

871 篇文章 14 订阅
695 篇文章 17 订阅

概述

用户文件:文件所有者为登录到该终端设备的用户,包括用户私有的 图片、视频 、音频、文档等。

  1. 用户文件存放在用户目录下,归属于该设备上登录的用户。

  2. 用户文件存储位置主要分为 内置存储 、 外置存储 。

  3. 应用对用户文件的创建、访问、删除等行为,需要提前获取用户授权,或由用户操作完成。

用户文件存储位置

内置存储

内置存储,是指用户文件存储在终端设备的内部存储设备(空间)上。内置存储设备无法被移除。内置存储的用户文件主要有:

  • 用户特有的文件:这部分文件归属于登录该设备的用户,不同用户登录后,仅可看到该用户自己的文件。

按照这些文件的特征/属性,以及用户/应用的使用习惯,可分为:

  • 图片/视频类媒体文件

所具有的特征包括拍摄时间、地点、旋转角度、文件宽高等信息,以媒体文件的形式存储在系统中,通常是以所有文件、相册的形式对外呈现,不会展示其在系统中存储的具体位置。

  • 音频类媒体文件

所具有的特征包括所属专辑、音频创作者、持续时间等信息,以媒体文件的形式存储在系统中,通常会以所有文件、专辑、作家等形式对外部呈现,不会展示其在系统中存储的具体位置。

  • 其他文件(统称为文档类文件)

以普通文件的形式存储在系统中,该类文件既包括普通的文本文件、压缩文件等,又包括以普通文件形式存储的图片/视频、音频文件,该类文件通常是以目录树的形式对外展示。

  • 多用户共享的文件:用户可以通过将文件放在共享文件区,实现多个用户之间文件的共享访问。

共享文件区的文件,也是以普通文件的形式存储在系统中,以目录树的形式对外展示。

外置存储

外置存储,是指用户文件存储在外置可插拔设备上(如SD卡、U盘等)。外置存储设备上的文件,和内置存储设备共享区文件一样,可以被所有登录到系统中的用户看到。

外置存储设备具备可插拔属性,因此系统提供了设备插拔事件的监听及挂载功能,用于管理外置存储设备,,该部分功能仅对系统应用开放。

外置存储设备上的文件,全部以普通文件的形式呈现,和内置存储设备上的文档类文件一样,采用目录树的形式对外展示。

uri介绍

用户文件uri是文件的唯一标识,在对用户文件进行访问与修改等操作时往往都会使用到uri,不建议开发者解析uri中的片段用于业务代码开发,不同类型的uri使用方式将在下文详细介绍。

uri的类型

uri类型可以归纳为文档类uri和媒体文件uri两类

  • 文档类uri:由picker拉起文件管理器选择或保存返回,以及通过fileAccess模块获取。具体获取方式参见 文档类uri获取方式 。
  • 媒体文件uri:由picker通过拉起图库选择图片或者视频返回,通过photoAccessHelper模块获取图片或者视频文件的uri,以及通过userFileManager模块获取图片、视频或者音频文件的uri。具体获取方式参见 媒体文件uri获取方式 。

文档类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获取方式

  1. 通过 DocumentViewPicker接口 选择或保存文件,返回选择或保存的文件uri。

  2. 通过 AudioViewPicker接口 选择或保存文件,返回选择或保存的文件uri。

  3. 通过 PhotoViewPicker.save接口 保存文件,返回保存的文件uri。

文档类uri的使用方式

normal等级的应用使用此类uri的方式只能通过 fs模块 进行进一步处理,其他模块使用此uri是会报没有权限的错误。示例代码参见picker中的 选择文档类文件 和 保存文档类文件 。

媒体文件uri

媒体文件uri介绍

媒体文件uri的格式类型为:

图片uri格式:

  • ‘file://media/Photo//IMG_datetime_0001/displayName.jpg’

视频uri格式:

  • ‘file://media/Photo//VID_datetime_0001/displayName.mp4’

音频uri格式:

  • ‘file://media/Audio//AUD_datetime_0001/displayName.mp3’

其中各个字段表示的含义为:

uri字段说明
‘file://media’表示这个uri是媒体文件。
‘Photo’Photo表示这个uri是媒体文件中的图片或者视频类文件。
‘Audio’表示这个uri是媒体文件中的音频类文件。
‘’表示在数据库中多个表中处理后的值,并不是指表中的file_id列,注意请不要使用此id去数据库中查询具体文件。
‘IMG_datetime_0001’表示图片文件在用户文件系统中存储的文件名去掉后缀剩下的部分。
‘VID_datetime_0001’表示视频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。
‘AUD_datetime_0001’表示音频文件在用户文件系统中存储的文件名去掉后缀剩下的部分。

媒体文件uri获取方式

  1. 通过 PhotoViewPicker.select接口 选择媒体文件,返回选择的媒体文件文件的uri。

  2. 通过 photoAccessHelper模块 中的 getAssets 或 createAsset 接口获取媒体文件对应文件的uri。

媒体文件uri的使用方式

normal等级的应用使用此类uri可以通过 photoAccessHelper模块 进行进一步处理。示例代码参见媒体资源使用指导中的 指定URI获取图片或视频资源 。此接口需要申请相册管理模块读权限’ohos.permission.READ_IMAGEVIDEO’,在使用中需要注意应用是否有此权限。

若normal等级的应用不想申请权限也可以通过临时授权的方式使用 PhotoViewPicker.select接口 得到的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’添加日期(添加文件时间距1970年1月1日的秒数值)。
DATE_MODIFIED‘date_modified’修改日期(修改文件时间距1970年1月1日的秒数值,修改文件名不会改变此值,当文件内容发生修改时才会更新)。
DURATION‘duration’持续时间(单位:毫秒)。
WIDTH‘width’图片宽度(单位:像素)。
HEIGHT‘height’图片高度(单位:像素)。
DATE_TAKEN‘date_taken’拍摄日期(文件拍照时间距1970年1月1日的秒数值)。
ORIENTATION‘orientation’图片文件的方向。
TITLE‘title’文件标题。

下面为通过临时授权方式使用媒体文件uri进行获取缩略图和读取文件部分信息的示例代码:

import { picker } from '@kit.CoreFileKit';
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 picker.PhotoSelectOptions();
    PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
    PhotoSelectOptions.maxSelectNumber = 1;
    let photoPicker = new picker.PhotoViewPicker();
    photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: picker.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', err);
      }
    });
  } catch (error){
    console.error('uriGetAssets failed with err: ' + JSON.stringify(error));
  }
}

import { BusinessError } from '@kit.BasicServicesKit';
import { Want } from '@kit.AbilityKit';
import { common } from '@kit.AbilityKit';
import { fileAccess } from '@kit.CoreFileKit';

// context 是EntryAbility 传过来的context
let context = getContext(this) as common.UIAbilityContext;
async function example() {
    let fileAccessHelper: fileAccess.FileAccessHelper;
    // wantInfos 从getFileAccessAbilityInfo()获取
    let wantInfos: Array<Want> = [
      {
        bundleName: "com.ohos.UserFile.ExternalFileManager",
        abilityName: "FileExtensionAbility",
      },
    ]
    try {
      fileAccessHelper = fileAccess.createFileAccessHelper(context, wantInfos);
      if (!fileAccessHelper) {
        console.error("createFileAccessHelper interface returns an undefined object");
      }
      // 以内置存储目录为例
      // 示例代码sourceUri表示Download目录,该uri是对应的fileInfo中uri
      // 开发者应根据自己实际获取的uri进行开发
      let sourceUri: string = "file://docs/storage/Users/currentUser/Download/one.txt";
      // 将文件复制到的位置uri
      let destUri: string = "file://docs/storage/Users/currentUser/Documents";
      // 如果文件名冲突,要使用的文件名
      let displayName: string = "file1.txt";
      // 存放返回的uri
      let fileUri: string;
      try {
        // 复制文件返回该文件的uri
        fileUri = await fileAccessHelper.copyFile(sourceUri, destUri, displayName);
        if (!fileUri) {
          console.error("copyFile return undefined object");
        }
        console.log("copyFile success, fileUri: " + JSON.stringify(fileUri));
      } catch (err) {
        let error: BusinessError = err as BusinessError;
        console.error("copyFile failed, errCode:" + error.code + ", errMessage:" + error.message);
      }
    } catch (err) {
      let error: BusinessError = err as BusinessError;
      console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message);
    }
  }

鸿蒙全栈开发全新学习指南

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值