当前位置: 首页 > article >正文

鸿蒙NEXT API使用指导之文件压缩和邮件创建

鸿蒙NEXT API 使用指导

  • 一、前言
  • 二、邮件创建
    • 1、拉起垂类应用
    • 2、 UIAbilityContext.startAbilityByType 原型
      • 2.1、wantParam
      • 2.2、abilityStartCallback 与 callback
    • 3、拉起邮箱类应用
      • 3.1、单纯拉起邮箱应用
      • 3.2、传入带附件的邮件
  • 三、压缩文件
    • 1、认识 zlib
    • 2、压缩处理
      • 2.1、单文件压缩
      • 2.2、多文件压缩
    • 3、解压缩处理
    • 4、获取文件信息

一、前言

上一篇,由于篇幅所限,并未对实现问题反馈功能所使用的两个核心系统 API,进行较为细致的使用说明,更为提及使用它们时应该注意的地方,为了避免初学者掉坑,本人特意撰写本篇文章进行补充。

二、邮件创建

邮件,对于普通人来说,或许是一个知道但用得不多的通讯工具,然而,在程序员群体,邮件确实使用频率相当高的,因为众多代码托管平台或开发者平台,都会基于邮箱进行账号注册,并且邮箱这种工具在联系相关开发者时,要比流行的即时通讯工具更为有效得多,毕竟很容易集成到开发者自己开发的相关系统平台中。

1、拉起垂类应用

言归正传,在鸿蒙 NEXT 应用开发框架中中,如果像拉起手机系统已安装的邮箱应用,并且传入一封内容填写好的邮件,是完全有现成 API 可以使用的,就是 UIAbilityContext.startAbilityByTypeUIExtensionContentSession.startAbilityByType,想对来说,前者的使用更为简便,而在实现 TxtEdit 的问题反馈功能时,也是用了它,所以,本文重点了解前者,后者还请移步官方文档。

在 API13 版本中,UIAbilityContext.startAbilityByType 支持拉起的应用类型有如下:
在这里插入图片描述
因此,想要拉起邮箱类应用,只需将 type 参数设置为 mail 即可,具体来说就是形如下面的代码:

this.ctx.startAbilityByType("mail", wantParam, callback, 
	(err) => { ... });

2、 UIAbilityContext.startAbilityByType 原型

UIAbilityContext.startAbilityByType 方法的声明原型如下:
在这里插入图片描述
有四个必传参数,并且第一个参数就是指定应用类型的参数。按照参数的声明顺序,下面我们了解一下剩余的三个参数的传值。

2.1、wantParam

在 UIAbilityContext.startAbilityByType 方法的第二个参数 wantParam,是一个 Record<string, Object> 类型,作用是设置拉起邮箱应用时需要一并传入的数据,针对 type=mail 时,这个 wantParam 可以传入的合法参数选项有如下:
在这里插入图片描述
都不是必填的,有两个需要注意的细节:
1) string 类型或 string[] 类型的数据值,都必须用encodeURI 编码一下;
2)邮箱地址,如收件人地址,在仅需填写一个邮箱地址的时候,如果错误地设置成 string 类型,即没有携带上中括号,那么就会出现能够成功拉起邮箱应用,但不会进入邮件编辑界面,也不会有任何错误抛出。

wantConstantFlags 的枚举值有如下几个:
在这里插入图片描述

这个 wantConstantFlags 选项,在需要创建带附件的邮件时,相当重要,设置错误将导致无法读取文件内容到邮件中。

2.2、abilityStartCallback 与 callback

abilityStartCallback 是一个 AbilityStartCallback 类型的参数,在 UIAbilityContext.startAbilityByType 中的作用,就是提供获取执行结果道德入口

callback 则是一个 AsyncCallback<void>,为异步回调,用于获取接口调用是否成功。

这两个回调函数参数的区别,就在于 abilityStartCallback 是任务粒度的,而 callback 是接口粒度的,如此设计,是因为接口调用是否成功,与任务执行是否成功,是两码事,任务执行失败而接口调用不一定失败,但接口调用失败则任务执行一定失败。

3、拉起邮箱类应用

3.1、单纯拉起邮箱应用

如果不需要在拉起邮箱应用时,传入一封邮件,那么,wantParam 应该怎么传参呢?

思考一下,前面提到的针对邮箱类应用的 wantParam 选项,为什么都设置成非必填呢?如果传入一个空值的 wantParam 去拉取邮箱类应用,会有什么样的执行结果呢?想要知道会发生什么,不妨写段代码在真机上跑一下:

let callback: common.AbilityStartCallback = {
 onError: (code: number, name: string, message: string) => {
   Logger.error(`拉起邮箱失败,错误码:${code}, 错误名:${name}, 错误信息:${message}`, TAG)
   promptAction.showToast({
     message: "调用邮箱失败,请稍后重试",
     duration: 3000
   })
 },
 onResult: (result) => {
   Logger.info(`拉起邮箱成功,结果: ${JSON.stringify(result)}`, TAG)
   promptAction.showToast({
     message: '调用邮箱成功',
     duration: 3000
   })
 }
};
this.ctx.startAbilityByType("mail", {}, callback, (err) => {
 if (err) {
   Logger.error(`startAbilityByType调用失败,错误信息:${err.message}`, TAG)
 }
 Logger.info(`startAbilityByType调用成功`, TAG)
})

执行之后,首先会弹出应用选择面板,选择目标邮箱后,会进入目标邮箱应用并跳转到邮件新建界面。

这显然与我们想要的单纯进入邮箱应用主页,不进入邮件编辑页面,并不一致,为了达到这个目的,就应当从空传的 wantParam入手了;还记得前面介绍 wantParam 合法选项时,提到注意细节吗?其中就有一个强调邮箱地址要用 string[] 类型透传,但如果我们有意传成 string 类型,就如下面的代码这般:

const wantParam: Record<string, Object>  = {
  'sceneType': 1,
  'email': '15014366986@163.com', // 收件人邮箱地址
};
this.ctx.startAbilityByType("mail", wantParam, callback, (err) => {
  if (err) {
    Logger.error(`startAbilityByType调用失败,错误信息:${err.message}`, TAG)
  }
  Logger.info(`startAbilityByType调用成功`, TAG)
})

就能实现我们的目的,不过,显而易见,这种实现方式需要慎重,因为后续的 API 迭代中,可能会对 wantParam 中的选项的类型进行强校验,校验不通过就抛错。

3.2、传入带附件的邮件

利用 wantParam,我们可以实现调用邮箱应用并进入编辑界面,并且提前填写好相关内容,无需用户自己手动输入信息,比如利用下面的 wantParam 传入带附件的邮件内容:

const wantParam: Record<string, Object>  = {
  'sceneType': 1,
  'email': [encodeURI("wy1589461@163.com")], // 收件人邮箱地址,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码
  'subject': encodeURI('TxtEdit用户使用问题反馈'), // 邮件主题,对内容使用encodeURI()方法进行url编码
  'body': encodeURI(mailBody), // 邮件正文,对内容使用encodeURI()方法进行url编码
  'ability.params.stream': [encodeURI(uri)], // 附件uri,多值以逗号分隔,对数组内容使用encodeURI()方法进行url编码
  'ability.want.params.uriPermissionFlag': wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION
};

这里给出的案例,显然是主送一人、无抄送和密送的情况,如果需要抄送和密送,那么就需要为 cc 选项和 bcc 选项设置邮箱地址;邮件要携带的附件,以[encodeURI(文件URI)]的形式,为选项 ability.params.stream 设置值,并且为了保证有权限去读取目标文件中的内容,ability.want.params.uriPermissionFlag 必须设置成 wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION

三、压缩文件

ability.params.stream 接受 string[] 类型的数据值来看,邮件附件是支持同时携带多份文件的,但有时候为了尽可能减小邮件的体积、降低对带宽的占用和提供传输效率,将多份需要邮件发送的文件压缩成一个压缩包进行发送,是常用的操作。

除了邮件,很多网络传输文件场景中,也比较推荐以压缩包的形式,去传输多份文件,同时,大文件的网络传输,用压缩包的形式进行传输,可以极大的提高成功率。

在移动端,处理压缩包的情况比较少见,但这并不意味着手机操作系统就没有相应的功能,实际上,安卓系统和鸿蒙系统都支持打开、解压缩一定格式的压缩包文件,而目前使用量最大的鸿蒙4.x版本的系统中,用手机管家清理加速的时候,是能够对不常用应用和文件进行压缩处理、从而降低对存储空间的占用。

1、认识 zlib

在鸿蒙NEXT 开发框架中,有一个 @ohos.zlib 模块,该模块下提供用于文件压缩与解压缩的相关API,并且开箱可用,主要支持 .zip.gzip 两种压缩包文件格式。
所有 API 可以大致划分为压缩处理、解压缩处理和获取文件信息三大类。

2、压缩处理

遵循先有鸡后有蛋的原则,我们先看压缩处理相关的 API。
通过归纳官方文档,梳理出关于文件压缩处理的 API,主要有:
1)zlib.compressFile 与 zlib.compressFiles
2) Checksum.adler32 与 Checksum.adler32Combine、Checksum.crc32与Checksum.crc32Combine、Checksum.crc64
3)Zip.compress 与 Zip.compressBound,Zip.deflateInit 与 Zip.deflateInit2,Zip.deflate 等 Zip.deflateXXXX
4)Gzip.write

从使用难易的角度来说,第一组是最容易使用的,所以 ,本文重点介绍,后面的几组供学有余力的读者,前往官方文档仔细摸索。

2.1、单文件压缩

开始介绍前,给大家普及一个知识点,在计算机操作系统中,目录也是文件,一种格式比较特殊的文件

单文件压缩,可以使用zlib.compressFile,这里传授大家一个经验,就是阅读API文档或者在代码提示中选择API时,一定要留意API名称的单复数,单数形式命名的API,往往只能一次处理一份数据,而复数形式命名的API 则可以一次处理多份数据,举一反三,大家在封装自己的工具类的时候,也应该遵循这种规则。

zlib.compressFile 一共如下四个参数:
在这里插入图片描述
1)inFile 是待压缩的文件或目录,不论是文件还是目录,对应的路径都必须是沙箱路径,并且如果是文件夹,那么该文件夹应为非空文件夹,否则会引发解压缩操作报错。
2)outFile 是保存压缩数据的压缩包文件路径,注意文件名取名为xxx.zip
3)options,压缩配置相关的选项:
a、level,压缩等级,合法枚举值如下:
在这里插入图片描述
b、memLevel,压缩过程中内存使用程度
在这里插入图片描述
c、strategy,压缩策略
在这里插入图片描述

2.2、多文件压缩

压缩多文件时,虽然可以选择将整个目录进行压缩,然而,有时候,需要压缩的目标文件,并不是所在目录下的所有文件,仅仅是其中的几个,针对这种应用场景,对多个指定文件或指定目录进行压缩的操作,就必须支持,而鸿蒙 NEXT 开发框架,通过 zlib.compressFiles 进行支持。
在这里插入图片描述
zlib.compressFiles 的方法参数,相对于前面的单文件压缩方法,少了一个回调函数参数,并且第一个参数更名为 inFiles、使用 Array<string> 类型

3、解压缩处理

zlib 模块中,针对解压缩处理,同样提供了多组 API,但本文为了内容的相关性,这一节只介绍 zlib.decompressFile 的使用。

就解压缩来说,并不存在单文件和多文件的区分,目前应用市场上的压缩包工具,解压缩操作也都仅支持一次处理一个压缩包文件。

zlib.compressFile 和 zlib.decompressFile,针对同步和异步场景,提供了不同实现,知其一便知其所有。
在这里插入图片描述
decompressFile 的参数结构,与 compressFile 几乎是一样的,而这也是众多三方 API 库共同具有的特征,所以,也是我们应当学会和掌握的编程细节。

4、获取文件信息

对于解压缩功能,往往在真正进行解压缩之前,会先读取压缩包的相关文件信息,比如获取原始文件的大小,然后决定是否要执行解压缩操作,从而避免将用户的存储空间撑爆。

有需求便有市场,所以,zlib 模块提供了大量的用户获取压缩包文件信息的相关 API,有兴趣的到官方文档上仔细了解,这里重点介绍 zlib.getOriginalSize

zlib.getOriginalSize 方法原型如下:
在这里插入图片描述
参数结构比较简单,仅需传入压缩包所在的沙箱路径即可,而压缩包对应的原始文件的大小,会以异步回调的方式返回,简单的使用如下:

et compressedFile = '/data/storage/el2/base/temp/test.zip';

try {
  zlib.getOriginalSize(compressedFile).then((data: number) => {
    console.info(`getOriginalSize success. getOriginalSize: ${data}`);
  }).catch((errData: BusinessError) => {
    console.error(`errData is errCode:${errData.code}  message:${errData.message}`);
  })
} catch (errData) {
  let code = (errData as BusinessError).code;
  let message = (errData as BusinessError).message;
  console.error(`errData is errCode:${code}  message:${message}`);
}

由于文件压缩与解压缩,在移动端应用场景中,并不多见,同时,为了避免本文篇幅过长,这里就不再给出文件压缩与解压缩的详细使用案例,请读者见谅。


http://www.kler.cn/a/539721.html

相关文章:

  • 【DeepSeek × Postman】请求回复
  • QML 和 Qt Quick 介绍
  • NodeList 对象
  • 消息队列MQ
  • 浅析Ruby类污染及其在Sinatra框架下的利用
  • opencv图像处理
  • 【Spring】Spring MVC入门(一)
  • 如何将 Jupyter Notebook (.ipynb) 文件转换为 Python (.py) 文件
  • Git 常见错误与解决方案全指南
  • 安装perl-DBD-MySQL报错:Requires: libmysqlclient.so.18
  • C++ 设计模式 - 访问者模式
  • MySQL数据库 - 阶段性体系总结
  • 【Vue3路由小技巧】用Hash模式打造流畅体验!
  • 【kafka系列】Topic 与 Partition
  • x小兔鲜vue.js
  • C#中的Frm_Welcome.Instance.Show(),是什么意思
  • c++ 输入输出笔记
  • 流氓软件一键屏蔽免疫工具Baidun Armor v3.2.1 绿色版
  • Centos Ollama + Deepseek-r1+Chatbox运行环境搭建
  • DeepSeek从入门到精通教程PDF清华大学出版
  • 【CubeMX+STM32】SD卡 文件系统读写 FatFs+SDIO+DMA
  • Java语言的区块链
  • kafka服务端之副本
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_version 函数
  • 51单片机俄罗斯方块开机动画
  • 物理信息机器学习(PIML)的基础探讨及技术实现