从零开始开发纯血鸿蒙应用之处理外部文件
从零开始开发纯血鸿蒙应用
- 一、外部文件
- 二、外部文件的访问形式
- 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”…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
