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

从零开始开发纯血鸿蒙应用之处理外部文件

从零开始开发纯血鸿蒙应用

  • 一、外部文件
  • 二、外部文件的访问形式
    • 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. 传输 两点之间传输&#xf…...

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”…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

深度学习习题2

1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...