从零开始开发纯血鸿蒙应用之处理外部文件
从零开始开发纯血鸿蒙应用
- 一、外部文件
- 二、外部文件的访问形式
- 1、主动访问
- 2、被动访问
- 三、代码实现
- 1、DocumentViewPicker
- 2、Ability Skills
- 3、onNewWant 函数
- 4、冷启动时处理外部文件
一、外部文件
对于移动端app来说,什么是外部文件呢?是那些存储在手机之外的存储介质中的文件吗?还是另有说法呢?
不同于桌面端的应用,手机操作系统对文件的访问控制非常严格,但app读写文件又是非常基础的需要,所以,像华为的鸿蒙系统以及苹果手机的iOS系统,都专门为app开辟了一个名为沙箱目录的目录区域,每个app都有自己专属的一个沙箱目录。
app在自己的沙箱目录里,可以很自由的进行文件的创建和读写、以及删除。对于存放在自己的沙箱目录中的文件,我称之为app的内部文件,而那些存储在自己的沙箱目录外的文件,或是存储在用户目录的文件,也或是存储在其他app的沙箱目录中的文件,我就称之为外部文件。
需要提醒的是,app的沙箱目录,在手机上用文件管理是看不到的,必须借助电脑上的专门工具,例如 DevEco Studio 才能看到。app 的沙箱目录一般路径为 /data/app/el2/100/base/[package name]/hap/entry。

对于 DevEco Studio 提供的 Device File Browser,我想多说两句,一是该工具提供了两种查看视图,普通文件视图和沙箱文件视图,第二种视图依赖于应用需要在 module.josn5 中开启 ohos.permission.INTERNET 权限;二是该工具并不是所有app的沙箱目录都可以查看:

二、外部文件的访问形式
外部文件的访问,主要有两种形式:主动访问和被动访问。
1、主动访问
所谓主动访问,就是app自己通过主动调用鸿蒙 API——picker,拉起文件选择面板,让用户去选择文件,然后再对目标文件进行内容读取和处理。

picker 会将选中的目标文件的File URI暴露出来,通过该File URI,就可以按图索骥进行文件操作,比如读取文件属性信息。
2、被动访问

如上图的这种操作,我相信大家平日的手机使用过程中,都会遇到。当一个文件不是当前app能够进行处理的时候,往往系统就会让你选中用其他应用去处理,实际上,这种方式就是让你选择的那个目标应用被动地进行外部文件的访问和处理。
在鸿蒙系统中,一个app默认是不具有被动处理外部文件的能力的,想要具备这种能力,需要app自己向系统声明,一般就是在 module.json5 文件中进行相关配置。
三、代码实现
1、DocumentViewPicker
鸿蒙系统针对不同的文件类型,提供了多种具体的 picker,其中,针对文件的就是这里即将进行介绍的DocumentViewPicker。
DocumentViewPicker 的使用非常简单,只需传入一个 option 即可:
const option: picker.DocumentSelectOptions = new picker.DocumentSelectOptions();
option.maxSelectNumber = 1;
option.fileSuffixFilters = ['.txt', '.log', '.csv', '.ini', '.conf', '.md', '.markdown', '.rtf', '.json','.xml', '.ets', '.java', '.py','.c', '.cpp', '.h', '.html']
const filePicker = new picker.DocumentViewPicker(this.ctx);
filePicker.select(option).then((uri) => {Logger.info(`选中的文件:${uri}`, TAG);const param: StrRouterParam = new StrRouterParam(uri[0]);router.pushUrl({url: "pages/ImportFilePage",params: param})
})
过程步骤可以描述为如下的几步:
1)创建一个 picker.DocumentSelectOptions 对象
2)使用 picker.DocumentSelectOptions 对象的属性,设置最大选中数、目标文件后缀等必要的文件过滤条件。picker.DocumentSelectOptions 对象一共有如下属性:
- maxSelectNumber:最大可选中数,值域范围1~500,如果是选择目录,那么该值只能为1;默认值为 1.
- defaultFilePathUri:指定选择文件或目录路径,即默认的文件或目录路径;没有默认值。
- fileSuffixFilters:目标文件的后缀;默认全部文件。
- selectMode:选择模式,用于设置支持选择的资源类型:文件、文件夹或二者混合;默认是文件。
- authMode:授权模式,默认为 false;当值为 true,则 defaultFilePathUri 必填,表示待授权的 uri。
3)利用 UI 上下文,创建一个 picker.DocumentViewPicker 对象,并使用该对象的 select 方法拉起文件选择面板,而select 方法的回调处理中,可以获得用户选中的文件的 uri,我这里是将该 uri 通过 router 路由携带跳转到专门用展示外部文件的页面里,然后展示文件内容:

2、Ability Skills
前面说了,应用默认是不具有被动处理外部文件的能力的,除非向系统声明了,而这个声明就是在 module.json5 中进行能力声明:

skills 标签里的 actions 标签,用于声明具体的能力动作,上面的ohos.want.action.viewData,就表示查看数据的操作;同样位于 skills 标签里面的 uris 标签,可以为 viewData 动作进行进一步的细化,声明支持何种类型的数据的查看,如上的配置,则表示支持通用纯文本文件类型的数据的查看。
通过类似如上的配置,当用户需要进入“使用其他应用打开文件”的场景时,系统就会判断待打开的文件,是否与应用在 module.json5 文件中声明的数据查看能力相符合,如果符合就会展示在应用候选中,否则就不展示。
3、onNewWant 函数
光在 module.json5 文件中声明 Ability Skills,尚不足以形成真正的处理外部文件的能力,因为传记录的文件uri 没有任何代码进行读取等文件操作,而想要实现这一步骤,就需要用到一个应用生命周期函数 onNewWant 函数。

当应用已经完成冷启动并进入后台运行状态时,用户的“选择某某app打开文件”的操作,就会触发该生命周期函数,而函数的 Want 参数里面,就包含了用户想要打开的文件的 File Uri,因此,就可以用类似如下的代码进行处理:

4、冷启动时处理外部文件
用户在其他app页面,选择用当前应用去打开文件时,当前应用可能并未完成冷启动,这时候,就不会触发 OnNewWant 函数,而是触发 onCreate 函数:

然而,由于 onCreate 函数早于 onWindowStageCreate 的执行,意味着 UI 进程还没开始,也就是页面跳转动作还不能进行,所以,在 onCreate 函数里面处理其他app传进来的文件,是不合适的,不妨移步到 onWindowStageCreate 函数中。

onWindowStageCreate 函数的参数,虽然没有 Want 对象,但是 this 上下文里面就有有一个 launchWant 实例,借助它依旧能够获取到其他app传入的文件 uri,由于 windowStage.loadContent 不像 router.push 那样携带参数,而 windowStage.loadContent 在被执行完成之前,应用主页未被渲染出来,router.push 依旧用不了,所以,我利用 AppStorage 去完成外部文件 uri 的透传:

在应用主页的 aboutToAppear 生命周期函数中,判断 AppStorage 中记录的 SignalConstants.SIGNAL_OUTFILE_URI 是否为非空字符串,如果是,则将对应的外部文件的 File Uri 通过 router.push 携带跳转到 ViewOutsideFile 页面,从而完成冷启动状态下对外部文件的处理。
相关文章:
从零开始开发纯血鸿蒙应用之处理外部文件
从零开始开发纯血鸿蒙应用 一、外部文件二、外部文件的访问形式1、主动访问2、被动访问 三、代码实现1、DocumentViewPicker2、Ability Skills3、onNewWant 函数4、冷启动时处理外部文件 一、外部文件 对于移动端app来说,什么是外部文件呢?是那些存储在…...
Spring中三级缓存详细讲解
1、Spring三级缓存是什么,过程是怎么样的? Spring 中的三级缓存主要用于单例 Bean 的生命周期管理,特别是在循环依赖时,它通过不同阶段暴露 Bean 实例来确保依赖注入的顺利完成。缓存的内容如下: 一级缓存 (singleton…...
论文阅读:《Whole-animal connectomes of both Caenorhabditis elegans sexes》
一 论文整体概述 论文下载链接:《Whole-animal connectomes of both Caenorhabditis elegans sexes》 补充信息和额外数据:https://www.nature.com/articles/s41586-019-1352-7 1. 作者期刊背景 该论文由Scott W. Emmons,David H. Hall等…...
嵌入式开发之STM32学习笔记day03
STM32之ADC(模拟数字转换器) 1 ADC简述2 ADC转换时间3 ADC转化结果存放机制4 ADC转化结果存放机制5 ADC电压转换 1 ADC简述 ADC(Analog-Digital Converter)模拟—数字转换器;ADC可以将引脚上连续变化的模拟电压转换为…...
windows10 安装 Golang 版本控制工具g与使用
下载包:https://github.com/voidint/g/releases 解压, 并添加到环境变量 g 常用命令 查询当前可供安装的stable状态及所有的 go 版本 # stable 版本 g ls-remote stable# 所有版本 g ls-remote安装目标 go 版本1.23.4g install 1.23.4切换到已安装的…...
SpringBoot 使用 Cache 集成 Redis做缓存保姆教程
1. 项目背景 Spring Cache是Spring框架提供的一个缓存抽象层,它简化了缓存的使用和管理。Spring Cache默认使用服务器内存,并无法控制缓存时长,查找缓存中的数据比较麻烦。 因此Spring Cache支持将缓存数据集成到各种缓存中间件中。本文已常…...
R数据分析:多分类问题预测模型的ROC做法及解释
有同学做了个多分类的预测模型,结局有三个类别,做的模型包括多分类逻辑回归、随机森林和决策树,多分类逻辑回归是用ROC曲线并报告AUC作为模型评估的,后面两种模型报告了混淆矩阵,审稿人就提出要统一模型评估指标。那么肯定是统一成ROC了,刚好借这个机会给大家讲讲ROC在多…...
数据结构与算法之二叉树: LeetCode 654. 最大二叉树 (Ts版)
最大二叉树 https://leetcode.cn/problems/maximum-binary-tree/ 描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值递归地在最大值 左边 的 子数组前缀上 构建左子树递归地在最大值…...
Linux 容器漏洞
定义:Linux 容器漏洞是指在容器技术(如 Docker、LXC 等)运行环境中存在的安全弱点。这些漏洞可能存在于容器镜像本身、容器运行时(如 runc)、容器编排工具(如 Kubernetes)或者容器与主机之间的交…...
file与io流(1)
-1- java.io.File类的使用 (1) 概述 File类及本章下的各种流,都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。(体会万事万物皆…...
忘记了PDF文件的密码,怎么办?
PDF文件可以加密,大家都不陌生,并且大家应该也都知道PDF文件有两种密码,一个打开密码、一个限制编辑密码,因为PDF文件设置了密码,那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密? PDF和offi…...
Linux权限管理(用户和权限之间的关系)
Linux系列 文章目录 Linux系列一、Linux下用户类型二、普通权限的基本概念2.1、Linux中权限的类别2.2、Linux中权限对应的三种身份2.3、文件权限的标识 三、文件权限设置四、修改文件属主和属组4.1、chown修改文件的属主4.2、修改所属组 五、文件掩码六、目录权限 一、Linux下用…...
Python Selenium库入门使用,图文详细。附网页爬虫、web自动化操作等实战操作。
文章目录 前言1 创建conda环境安装Selenium库2 浏览器驱动下载(以Chrome和Edge为例)3 基础使用(以Chrome为例演示)3.1 与浏览器相关的操作3.1.1 打开/关闭浏览器3.1.2 访问指定域名的网页3.1.3 控制浏览器的窗口大小3.1.4 前进/后…...
【Uniapp-Vue3】使用defineExpose暴露子组件的属性及方法
如果我们想要让父组件访问到子组件中的变量和方法,就需要使用defineExpose暴露: defineExpose({ 变量 }) 子组件配置 父组件配置 父组件要通过onMounted获取到子组件的DOM 传递多个属性和方法 子组件 父组件...
【多模态LLM】英伟达NVLM多模态大模型训练细节和数据集
前期笔者介绍了OCR-free的多模态大模型,可以参考:【多模态&文档智能】OCR-free感知多模态大模型技术链路及训练数据细节,其更偏向于训练模型对于密集文本的感知能力。本文看一看英伟达出品的多模态大模型NVLM-1.0系列,虽然暂未…...
HTTP详解——HTTP基础
HTTP 基本概念 HTTP 是超文本传输协议 (HyperText Transfer Protocol) 超文本传输协议(HyperText Transfer Protocol) HTTP 是一个在计算机世界里专门在 两点 之间 传输 文字、图片、音视频等 超文本 数据的 约定和规范 1. 协议 约定和规范 2. 传输 两点之间传输…...
MySQL教程之:输入查询
如上一节所述,确保您已连接到服务器。这样做本身不会选择任何要使用的数据库,但没关系。在这一点上,了解一下如何发出查询比直接创建表、加载数据和从中检索数据更重要。本节介绍输入查询的基本原则,使用几个查询,您可…...
docker+ffmpeg+nginx+rtmp 拉取摄像机视频
1、构造程序容器镜像 app.py import subprocess import json import time import multiprocessing import socketdef check_rtmp_server(host, port, timeout5):try:with socket.create_connection((host, port), timeout):print(f"RTMP server at {host}:{port} is avai…...
不同音频振幅dBFS计算方法
1. 振幅的基本概念 振幅是描述音频信号强度的一个重要参数。它通常表示为信号的幅度值,幅度越大,声音听起来就越响。为了更好地理解和处理音频信号,通常会将振幅转换为分贝(dB)单位。分贝是一个对数单位,能…...
【17. 电话号码的字母组合 中等】
题目: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits “23”…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
