news 2026/6/6 0:12:49

鸿蒙开发--FileManagerServiceKit

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙开发--FileManagerServiceKit

HarmonyOS 文件管理服务:让你的应用支持"删除到回收站"

什么是文件管理服务

你有没有遇到过这种情况:不小心删了一个重要文件,然后就找不回来了?电脑上一般有回收站,删了文件还能从回收站里恢复。但手机上呢?很多手机 App 删除文件就是直接删了,没有后悔的机会。

文件管理服务(File Manager Service Kit)就是来解决这个问题的。它是鸿蒙生态下的文件管理服务,提供了"删除到回收站"的能力。简单说,就是让你的 App 删除文件时,不是直接删掉,而是放到回收站里,用户可以随时恢复。

你可能会问:回收站在哪?在鸿蒙系统里,回收站是系统级的功能,用户可以在文件管理器里找到。你只需要调用文件管理服务的接口,把文件"移到回收站"就行,剩下的事情系统会帮你处理。

核心功能

文件管理服务目前提供的核心功能就一个:

  1. 删除到回收站:把文件移到回收站,而不是直接删除

虽然功能看起来简单,但这个能力非常重要。想想看,你的 App 如果有文件管理功能,用户肯定会期望有回收站,就像电脑上的回收站一样。没有回收站的文件管理器,用户用起来总是提心吊胆的,生怕一不小心删错了东西。

环境搭建

硬件要求

  • 设备类型:华为手机、平板、PC/2in1
  • HarmonyOS 系统:HarmonyOS 5.0.5 Release 及以上

软件要求

  • DevEco Studio 版本:DevEco Studio 5.0.5 Release 及以上
  • HarmonyOS SDK 版本:HarmonyOS 5.0.5 Release SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装,跟着提示走就行
  2. 配置开发环境:确保网络环境正常,DevEco Studio 需要联网才能用
  3. 设备调试:使用真机进行调试,模拟器也可以

项目结构

└── entry/src/main ├── ets │ ├── entryability │ │ └── EntryAbility.ets // 程序入口类 │ └── pages │ └── Index.ets // 主界面 └── resources // 资源文件目录

项目结构非常简单,核心逻辑都在Index.ets里。这个 Codelab 的重点就是教你调用文件管理服务的接口,所以代码量不大。

第一步:导入模块

import{fileManagerService}from'@kit.FileManagerServiceKit';import{BusinessError}from'@kit.BasicServicesKit';import{common}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{picker}from'@kit.CoreFileKit';import{PromptAction}from'@kit.ArkUI';

导入的模块有点多,一个个来说:

  • fileManagerService:文件管理服务的核心接口,我们用它来调用"删除到回收站"功能。这是整个文章最重要的模块
  • BusinessError:错误处理用的。华为的 Kit 接口基本都用这个来返回错误信息,包括错误码和错误描述
  • common:获取上下文用的。调用文件管理服务接口时需要传入应用的上下文
  • hilog:日志工具,开发调试的时候看输出用的。出了问题也能查日志,建议别删
  • picker:文件选择器,让用户选择要删除的文件。你想啊,用户得先选中一个文件,才能删除它对吧
  • PromptAction:弹出提示用的,比如"删除成功"、"删除失败"这种提示框

第二步:定义日志标签

constdomain=0x0000;consttag='deleteTag';

定义日志的标签,方便在控制台里找到我们的日志输出。domain是日志的域,tag是标签名,你可以随便取,只要方便识别就行。

为什么要定义这个?因为鸿蒙系统里会有很多日志输出,如果你不加标签,根本找不到自己写的日志。就像在一堆信件里找自己的信,有个名字标记就好找多了。

第三步:创建文件选择器

letcontext:common.UIAbilityContext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;letpromptAction:PromptAction=this.getUIContext().getPromptAction();letselectOptions:picker.DocumentSelectOptions=newpicker.DocumentSelectOptions();selectOptions.defaultFilePathUri='file://docs/storage/Users/currentUser';letdocumentPicker=newpicker.DocumentViewPicker(context);

创建文件选择器的过程,我一行一行解释:

  1. 获取上下文(context):这是应用的运行环境,很多接口都需要传入这个参数。你可以理解为"当前页面的环境信息"
  2. 获取提示操作(promptAction):用来弹出提示信息,比如 Toast 提示。不获取这个的话,你就没办法弹提示了
  3. 创建选择选项(selectOptions):可以设置默认打开的路径。这里设置为用户文件目录,这样用户打开选择器时直接看到的就是自己的文件
  4. 创建文件选择器(documentPicker):用来让用户选择文件。这个选择器是系统提供的,长得和系统文件管理器一样

defaultFilePathUri设置了文件选择器打开时默认显示的路径。如果你不设置这个,选择器可能会打开一个默认目录,用户还得自己导航到想要的目录,体验不好。

第四步:选择文件并删除到回收站

documentPicker.select(selectOptions,async(err:BusinessError,documentSelectResult:Array<string>)=>{if(err){hilog.error(domain,tag,'DocumentViewPicker.select failed with err: '+JSON.stringify(err));return;}// 选择成功,处理文件});

调用documentPicker.select打开文件选择器。用户会看到一个系统文件选择界面,可以选择一个或多个文件。

选择完成后,回调函数会被调用:

  • 如果err有值,说明出了问题(比如用户取消了选择),打印错误信息然后 return
  • 如果err没有值,说明选择成功,documentSelectResult里就是用户选中的文件 URI 列表
try{for(leturiofdocumentSelectResult){hilog.info(domain,tag,'deleteToTrash start');constret:string=awaitfileManagerService.deleteToTrash(uri);hilog.info(domain,tag,'deleteToTrash end, ret:%{public}',ret);}promptAction.showToast({message:`delete success`,duration:5});}catch(error){hilog.error(domain,tag,`error.code:${error.code}, error.message:${error.message}`);promptAction.showToast({message:`delete failed, error.code:${error.code}, error.message:${error.message}`,duration:5});}

这是核心逻辑,我拆开来说:

  1. 遍历用户选择的所有文件:用户可能选了多个文件,所以用for...of循环处理
  2. 调用fileManagerService.deleteToTrash(uri):这是整个文章最重要的 API。它不会直接删除文件,而是把文件移到回收站里。用户可以在文件管理器的回收站里找到这些文件,随时恢复
  3. 全部成功后,弹出"删除成功"的提示:让用户知道操作完成了
  4. 如果出错了,弹出错误信息:可能是因为文件不存在、权限不足等原因

deleteToTrash的返回值是一个字符串,表示操作结果。你可以根据这个返回值判断是否成功。

为什么要用try...catch?因为删除文件可能会失败。比如文件已经被删了、文件路径不对、没有权限等等。如果不捕获异常,程序可能会崩溃。

完整代码

把上面的步骤合在一起,完整的代码是这样的:

import{fileManagerService}from'@kit.FileManagerServiceKit';import{BusinessError}from'@kit.BasicServicesKit';import{common}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';import{picker}from'@kit.CoreFileKit';import{PromptAction}from'@kit.ArkUI';constdomain=0x0000;consttag='deleteTag';@Entry@Componentstruct Index{build(){Column(){Button($r('app.string.select_files_to_delete')).onClick(async()=>{try{letcontext:common.UIAbilityContext=this.getUIContext().getHostContext()ascommon.UIAbilityContext;letpromptAction:PromptAction=this.getUIContext().getPromptAction();letselectOptions:picker.DocumentSelectOptions=newpicker.DocumentSelectOptions();selectOptions.defaultFilePathUri='file://docs/storage/Users/currentUser';letdocumentPicker=newpicker.DocumentViewPicker(context);documentPicker.select(selectOptions,async(err:BusinessError,documentSelectResult:Array<string>)=>{if(err){hilog.error(domain,tag,'DocumentViewPicker.select failed with err: '+JSON.stringify(err));return;}try{for(leturiofdocumentSelectResult){hilog.info(domain,tag,'deleteToTrash start');constret:string=awaitfileManagerService.deleteToTrash(uri);hilog.info(domain,tag,'deleteToTrash end, ret:%{public}',ret);}promptAction.showToast({message:`delete success`,duration:5});}catch(error){hilog.error(domain,tag,`error.code:${error.code}, error.message:${error.message}`);promptAction.showToast({message:`delete failed, error.code:${error.code}, error.message:${error.message}`,duration:5});}});}catch(error){leterr:BusinessError=errorasBusinessError;hilog.error(domain,tag,'DocumentViewPicker failed with err: '+JSON.stringify(err));}})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}}

整个流程就是:点击按钮 → 打开文件选择器 → 用户选择文件 → 调用deleteToTrash删除到回收站 → 显示结果提示。

看起来代码挺长的,但其实逻辑很简单。大部分代码都是在做准备工作(创建选择器、获取上下文),真正干活的就一行:fileManagerService.deleteToTrash(uri)

实际应用场景

文件管理服务在实际开发中有很多用途:

文件管理器

// 文件管理器中的删除功能asyncfunctiondeleteFileToTrash(uri:string){try{constret:string=awaitfileManagerService.deleteToTrash(uri);console.info('文件已移到回收站');// 可以在这里更新 UI,把文件从列表里移除}catch(error){console.error(`删除失败:${error.code},${error.message}`);// 提示用户删除失败}}

在文件管理器里,用户删除文件时,调用deleteToTrash把文件移到回收站,而不是直接删除。这样用户可以随时从回收站恢复文件。

你可能会问:那回收站满了怎么办?鸿蒙系统的回收站有自动清理机制,会按照先进先出的原则清理旧文件。你不需要自己管理回收站的空间。

笔记应用

// 笔记应用中删除附件asyncfunctiondeleteNoteAttachment(attachmentUri:string){try{awaitfileManagerService.deleteToTrash(attachmentUri);// 更新笔记,移除附件引用console.info('附件已移到回收站');}catch(error){console.error(`删除附件失败:${error.code}`);}}

在笔记应用里,用户删除笔记附件时,也可以用这个功能。附件被移到回收站,用户如果发现误删了,可以去回收站恢复。

图片编辑应用

// 图片编辑应用中删除原图asyncfunctiondeleteOriginalImage(imageUri:string){try{awaitfileManagerService.deleteToTrash(imageUri);console.info('原图已移到回收站');}catch(error){console.error(`删除原图失败:${error.code}`);}}

在图片编辑应用里,编辑完图片后,如果用户想删除原图,可以用这个功能把原图移到回收站。这样即使用户后悔了,也能从回收站找回来。

适用场景

文件管理服务适合以下场景:

  • 文件管理器:文件删除和回收站管理
  • 笔记应用:笔记附件的删除
  • 图片应用:图片文件的删除
  • 文档应用:文档文件的删除
  • 下载管理器:下载文件的删除

注意事项

  1. 文件权限:删除文件前,需要确保对文件有读写权限。可以通过文件选择器让用户授权,这是最简单的方式
  2. 文件 URI:要确保传入的文件 URI 是有效的,否则会删除失败。URI 格式一般是file://docs/...
  3. 回收站管理:删除到回收站的文件会占用存储空间,提醒用户定期清理回收站
  4. 错误处理:要做好错误处理,比如文件不存在、权限不足等情况。不要让程序因为删除失败就崩溃
  5. 用户体验:删除前最好给用户一个确认提示,避免误删。毕竟移到回收站虽然可以恢复,但多一步确认总是好的

核心流程图

删除文件到回收站的完整流程:

用户点击删除按钮

创建文件选择器

打开系统文件选择界面

用户是否选择了文件?

取消操作

获取文件 URI 列表

遍历每个文件 URI

调用 deleteToTrash 移到回收站

操作是否成功?

弹出删除成功提示

弹出删除失败提示

用户可在回收站恢复文件

文件管理服务的应用场景:

文件管理服务

文件管理器

笔记应用

图片编辑应用

下载管理器

文件删除与回收站管理

笔记附件删除

原图删除

下载文件清理

用户可随时从回收站恢复

总结

文件管理服务让你的应用支持"删除到回收站",核心流程:

  1. 导入文件管理服务模块
  2. 创建文件选择器,让用户选择要删除的文件
  3. 调用deleteToTrash把文件移到回收站
  4. 处理成功和失败的情况

虽然功能看起来简单,但"删除到回收站"是一个非常实用的功能。它让用户不再担心误删文件,提升了应用的用户体验。如果你的 App 有文件管理功能,一定要加上这个能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 0:11:41

LogExpert终极指南:Windows平台最强大的免费日志分析工具

LogExpert终极指南&#xff1a;Windows平台最强大的免费日志分析工具 【免费下载链接】LogExpert Windows tail program and log file analyzer. 项目地址: https://gitcode.com/gh_mirrors/lo/LogExpert 在Windows系统上进行日志分析时&#xff0c;你是否还在为海量日志…

作者头像 李华
网站建设 2026/6/6 0:10:46

为 LLM 预留“插座”:设计可插拔的 AI 能力底座

写在前面你好&#xff0c;我是 Evan。一名正在摸爬滚打的 Java 后端开发者&#xff0c;也是这个专栏的作者。 在智答 Agent 项目中&#xff0c;我踩过最大的坑不是模型选错、不是 Prompt 调不好&#xff0c;而是架构没有为 AI 预留扩展点。最初我们直接硬编码调用 OpenAI 的 AP…

作者头像 李华
网站建设 2026/6/6 0:09:40

VisualCppRedist AIO:Windows系统运行库缺失问题的终极解决方案

VisualCppRedist AIO&#xff1a;Windows系统运行库缺失问题的终极解决方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 当你在Windows系统上安装或运行软件时…

作者头像 李华
网站建设 2026/6/5 23:59:57

芋道源码企业级框架:从零到一构建企业级Java应用的高效指南

芋道源码企业级框架&#xff1a;从零到一构建企业级Java应用的高效指南 【免费下载链接】ruoyi-spring-boot-all 芋道源码(无遮羞布版) 项目地址: https://gitcode.com/gh_mirrors/ru/ruoyi-spring-boot-all 在当今快速发展的企业应用开发领域&#xff0c;芋道源码企业级…

作者头像 李华
网站建设 2026/6/5 23:55:07

2026毕业生降AIGC工具盘点:省时省力+高分适配哪家强?

一、测评背景&#xff1a;AI检测步入语义溯源新阶段 2026年国内高校已全面落地知网4.0、维普2026版、万方学术风控3.0三大AIGC溯源审核体系&#xff0c;检测逻辑彻底跳出传统关键词词频匹配的局限&#xff0c;升级为语义逻辑溯源模式&#xff0c;新增段落结构相似度、用户写作习…

作者头像 李华
网站建设 2026/6/5 23:47:40

ros2 controller

1.Controller ManagerController Manager/ \/ \ joint_trajectory_controller InexbotHardware↓ ↓产生目标关节角 调用 servoJ / 读真实角度是一个大管家&#xff0c;统管很多控制器2.joi…

作者头像 李华