【鸿蒙心迹】HarmonyOS preview 预览文件 Kit 的入门讲解(配套后端代码)

【鸿蒙心迹】HarmonyOS preview 预览文件 Kit 的入门讲解(配套后端代码)

HarmonyOS preview 预览文件 Kit 的入门讲解(配套后端代码)

本文以实际工程为例,快速上手 HarmonyOS 元服务 的文件预览能力(PreviewKit),并配套一个后端用于提供示例文件。示例工程路径:

  • 客户端(HarmonyOS 端):client
  • 后端(Node.js):server


image-20251112091151694

上图是将 1个pdf文件和3个图片一起预览,那么就只会现实第1个预览窗口。

下图是移除pdf文件,将3个同类型的图片放在一起预览

image-20251112091518239

为了方便演示功能,需要先将一些可以预览的文件下载到元服务的沙箱内,是基于这个原因我们才需要引入后端来模拟这个下载的环境,所以元服务内需要先实现下载文件,存储到沙箱,然后再使用预览API filePreview.openPreview预览沙箱内的文件。

1. 工程结构与目标

  • client/entry/src/main/ets/pages/Index.ets:演示并发下载 4 个文件(1.pdf1.png2.png3.png)并一次性预览。
  • server/index.jsserver/public/:提供静态文件下载接口 /file/:filename

目标:

  • 点击“下载”按钮,并发下载上述 4 个文件到应用沙箱目录。
  • 下载成功后点击“预览”,一次性打开最多 4 个文件的预览窗口。

2. PreviewKit 的核心:filePreview.openPreview

HarmonyOS 提供了预览能力包 @kit.PreviewKit。在 ETS 代码中引入:

import{ filePreview }from'@kit.PreviewKit';import{ fileUri }from'@kit.CoreFileKit';

核心调用是:

// 先准备多个文件的预览信息const prewList: filePreview.PreviewInfo[]=[]for(let i =0; i < count; i++){const item =this.lastDownloadedList[i];const fileInfo: filePreview.PreviewInfo ={ title: item.name,// 预览标题 uri: fileUri.getUriFromPath(item.path),// 将沙箱路径转成 Uri mimeType: item.mime ||'application/octet-stream',// MIME 类型}; prewList.push(fileInfo)}// 一次性打开多个预览窗口 filePreview.openPreview(uiContext, prewList).then(()=>{// 打开成功}).catch((err: BusinessError)=>{// 打开失败处理});

说明:

  • PreviewInfo 至少需要 titleurimimeType
  • uri 使用 fileUri.getUriFromPath(沙箱文件路径) 构造。
  • 支持一次性传入一个 PreviewInfo[],实现多文件预览。
图片占位:请补充一次性预览 4 个文件的窗口布局截图,标注窗口标题与 MIME 类型展示位置。

3. 并发下载与状态反馈(客户端)

示例使用 Promise.allSettled 并发下载 4 个后端文件,并按项展示“成功/失败”状态:

// 计划 + 状态@Localprivate plannedFiles: DownloadPlan[]=[];@Localprivate itemStatuses:string[]=[];@Localprivate isDownloading:boolean=false;@Localprivate statusMessage:string='';// 初始化计划(aboutToAppear)this.plannedFiles =[newDownloadPlan('1.pdf',`${this.serverBase}/1.pdf`),newDownloadPlan('1.png',`${this.serverBase}/1.png`),newDownloadPlan('2.png',`${this.serverBase}/2.png`),newDownloadPlan('3.png',`${this.serverBase}/3.png`)];this.itemStatuses =['未下载','未下载','未下载','未下载'];// 点击“下载”this.isDownloading =true;this.statusMessage ='下载中...';this.itemStatuses =newArray(this.plannedFiles.length).fill('下载中...');const promises:Promise<DownloadInfo>[]=this.plannedFiles.map(p =>this.downloadFile(p.url));const settled =awaitPromise.allSettled(promises);// 汇总结果并一次性触发 UI 刷新const successes: DownloadInfo[]=[];const nextStatuses:string[]=newArray(this.plannedFiles.length).fill('未下载');for(let i =0; i < settled.length; i++){const name =this.plannedFiles[i].name;const r = settled[i];if(r.status ==='fulfilled'){ successes.push(r.value); nextStatuses[i]=`✓ 下载成功:${name}`;}else{ nextStatuses[i]=`✗ 下载失败:${name}(${this.errorToString(r.reason as Object)})`;}}this.itemStatuses = nextStatuses;// 重新赋值以触发 UI 刷新this.lastDownloadedList = successes;this.isDownloading =false;

UI 渲染建议:

  • 使用 ForEach(this.plannedFiles, ...) 动态渲染状态行,避免硬编码索引。
  • 将与 UI 绑定的字段用 @Local@State 修饰,并“重新赋值数组”以触发刷新(不要在原数组上就地修改元素)。
图片占位:请补充“下载中→成功/失败”逐项状态变化的截图,便于读者理解响应式刷新。

4. HTTP 下载的细节与 ArkTS 限制规避

  • MIME 与扩展名:示例通过扩展名推断 MIME,若扩展名缺失则从响应头的 Content-Type 推断。
  • ArkTS 限制:不建议直接 data.header['Content-Type'] 索引;示例使用序列化 + 正则方式提取避免 ArkTS 索引限制。
// 通过序列化响应头并用正则提取 Content-TypeprivatetryGetContentTypeHeader(headerObj: Object |null):string{if(!headerObj)return'';try{const json =JSON.stringify(headerObj);if(!json)return'';const match = json.match(/"content-type"\s*:\s*"([^"]+)"/i);return match && match.length >1? match[1]:'';}catch(_){return'';}}

保存文件:

const filePath =`${this.filesDir}/${fileName}`;if(fileIo.accessSync(filePath)){ fileIo.unlinkSync(filePath);}const file = fileIo.openSync(filePath, fileIo.OpenMode.CREATE| fileIo.OpenMode.WRITE_ONLY);const bytesWritten = fileIo.writeSync(file.fd, fileBuffer); fileIo.closeSync(file);

权限:

  • 客户端需要在 entry/src/main/module.json5 声明 ohos.permission.INTERNET 才能进行网络请求。

5. 后端:简单的静态文件下载接口

示例后端路径:d:\code\atoStudy\server,目录 public/ 放置 4 个演示文件。

核心路由:GET /file/:filename

后端的简单目录结构:

image-20251112092243514
// index.js(简版示例)const express =require('express');const path =require('path');const app =express(); app.get('/file/:filename',(req, res)=>{const filename = req.params.filename;const filePath = path.join(__dirname,'public', filename); res.sendFile(filePath);// 或根据需要设置 Content-Type}); app.listen(3000,()=>{ console.log('Server listening on http://localhost:3000');});

客户端请求地址示例:

private serverBase:string="http://192.168.5.2:3000/file";// 组合完整 URL 示例:`${this.serverBase}/1.pdf`
注意:请按真实局域网 IP 替换 192.168.5.2,并保证手机/模拟器与后端在同一网络。

6. 快速运行与验证

后端:

  • 安装依赖并启动:npm install && node index.js
  • 确认 public/ 下存在 1.pdf1.png2.png3.png

客户端:

  • module.json5 中确保已声明 ohos.permission.INTERNET
  • 构建并安装到设备/模拟器
  • 点击“下载”,观察逐项状态变化
  • 下载成功后点击“预览”,验证多窗口预览是否正常
图片占位:请补充上述过程的关键截图(如“权限声明处”、“下载成功状态”、“多窗口预览”)。

7. 常见问题与排查

  • 权限错误(如 code=201 / “Permission denied”):检查 ohos.permission.INTERNET 是否声明;确认真机/模拟器的网络可达性。
  • 404 或下载失败:确认后端路由 /file/:filename 存在且文件确实在 public/ 目录内;检查客户端 serverBase 地址是否正确。
  • MIME 与扩展名错配:优先使用后端返回的 Content-Type;如果缺失,则按扩展名推断。
  • UI 不刷新:在 ArkUI 中对数组进行“重新赋值”来触发刷新,避免原地修改元素(例如使用 this.itemStatuses = [...nextStatuses])。

8. 小结

filePreview.openPreview 是 HarmonyOS 文件预览能力的核心,支持一次性打开多文件预览。结合简单的后端静态文件服务与并发下载、响应式状态刷新,能够快速搭建一个“下载即预览”的演示工程。本文的示例工程完整覆盖了从后端文件提供、客户端下载与保存、到预览窗口打开的关键路径,适合作为入门教程与二次扩展的基础。

近期活动

最近想要想要考取 HarmonyOS 基础或者高级证书,或者快要获取的同学都可以点击这个链接,加入我的班级,考取成功有机会获得鸿蒙礼盒一份。

Read more

20分钟一篇!!!最好用详细的AI写作论文综述(开题报告、最新技术)方法总结(字数、时效性和参考文献都严格一致符合要求、参考文献和正文引用都真实存在),模型gemini 2.5 pro

具体流程: 在自己想要引用的网站,如ieee xplore、知网、web of science这些网站中使用高级搜索、找到自己想要引用的文献(也就是和自己写的方向高度相关的文献),选择指定的年份(如比较新的23-25年),然后批量选择后选中批量导出文献,选择自己需要的文献格式(ieee格式,中国国标格式等),然后将导出的文献保存在txt文件中,这些就是自己要引用的所有文献,一般建议多导出几十条,这样可以让AI从中挑选合适的论文,去除一些不适合的论文。 然后在gemini 2.5 pro模型中,开启联网模式(ground with google search),将自己的参考文献通过文件上传(没有的话就直接将参考文献复制粘贴到输入框里),然后贴入自己的prompt(也就是自己对这个生成论文的细节要求(如领域、题目、格式等要求),里面要提到“请基于我提供的参考文献【50篇ieee和20篇cnki的】,从中选取50篇合适的论文,撰写一篇学习报告”),然后生成后,检查一些参考文献是否真实,真实无误的话就没问题啦! prompt如下:  你是一名资深信息安全技术研究员,擅长文献检索、前

By Ne0inhk

Whisper 模型本地化部署:全版本下载链接与离线环境搭建教程

Whisper 模型本地化部署指南 一、模型版本与下载 Whisper 提供多种规模版本,可通过以下官方渠道获取: 1. GitHub 仓库 https://github.com/openai/whisper 包含最新代码、预训练权重和文档 * tiny.en / tiny * base.en / base * small.en / small * medium.en / medium * large-v2 (最新大模型) Hugging Face 模型库 所有版本下载路径: https://huggingface.co/openai/whisper-{version}/tree/main 替换 {version} 为具体型号: 二、离线环境搭建教程 准备工作 1.

By Ne0inhk
文心一言4.5开源模型测评:ERNIE-4.5-0.3B超轻量模型部署指南

文心一言4.5开源模型测评:ERNIE-4.5-0.3B超轻量模型部署指南

目录 * 引言:轻量化部署的时代突围 * 一.技术栈全景图:精准匹配的黄金组合 * 基础层:硬核环境支撑 * 框架层:深度优化套件 * 工具层:部署利器 * 二.详细步骤:精准匹配CUDA 12.6的黄金组合 * 准备环节 * 1.模型选择 * 2.配置实例 * 3.选择镜像 * 4.进入JupyterLab * 5.进入终端 * 6.连接到ssh * 系统基础依赖安装 * 1.更新源并安装核心依赖 * 2.安装 Python 3.12 和配套 pip * 解决 pip 报错 * 深度学习框架部署:PaddlePaddle-GPU深度调优 * FastDeploy-GPU企业级部署框架 * 1.安装FastDeploy核心组件 * 2.修复urllib3

By Ne0inhk

GitHub Copilot提示词终极攻略:从“能用”到“精通”的AI编程艺术

摘要:GitHub Copilot作为当前最强大的AI编程助手,其真正的价值不仅在于自动补全代码,更在于开发者如何通过精准的提示词工程与之高效协作。本文系统解析Copilot提示词的核心原理、设计框架与实战技巧,涵盖从基础使用到高级功能的完整知识体系。通过四要素框架、WRAP法则、多场景应用指南,结合表格、流程图等可视化工具,帮助开发者掌握与AI协作的编程范式,提升300%以上的开发效率。文章深度结合当今AI技术发展趋势,提供理论性、可操作性、指导性并存的全面攻略。 关键词:GitHub Copilot、提示词工程、AI编程、代码生成、开发效率、人机协作 🌟 引言:当编程遇见AI,一场思维范式的革命 “写代码就像与一位天才但有点固执的同事合作——你需要用它能理解的语言,清晰地表达你的意图。”这是我在深度使用GitHub Copilot六个月后的最大感悟。 2023年以来,AI编程助手从概念验证走向生产力工具的核心转变,标志着一个新时代的到来。GitHub Copilot不再仅仅是“自动补全工具”,而是具备问答、编辑、自动执行能力的AI开发伙伴。然而,许多开发者仍停留在基础使

By Ne0inhk