HarmonyOS鸿蒙Next中第三方应用可以读、写插入usb存储设备的doc文件吗

HarmonyOS鸿蒙Next中第三方应用可以读、写插入usb存储设备的doc文件吗 需求:现预期功能是,在应用点击时,获取 usb设备里面的文件,在获取后又删除对应的文件。
目前情况:
1、使用 DocumentViewPicker 读取文件,读取后 无法删除,
2、想使用 fileAccess ,像是需要权限 ohos.permission.FILE_ACCESS_MANAGER,这个权限获取的难度好像很大。

针对这种情况还有没有什么更好的办法?

7 回复

您好,使用DocumentViewPicker读取文件,读取后无法删除,可以使用deleteToTrash删除

调用select()接口拉起Picker应用界面进行文件选择,将文档类URI传入fileManagerService.deleteToTrash删除对应文件

import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import common from '@ohos.app.ability.common';
import { fileManagerService } from '@kit.FileManagerServiceKit';
@Entry
@Component
struct Index {
@State message:string='select'
  build() {
    Column() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(async () => {
          let uris: string[] = [];
          // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
          let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
          // 创建文件选择器实例
          let documentSelectOptions = new picker.DocumentSelectOptions
          const documentViewPicker = new picker.DocumentViewPicker(context);
          documentViewPicker.select(documentSelectOptions).then(async (documentSelectResult: Array<string>) => {
            // 文件选择成功后,返回被选中文档的URI结果集。
            uris = documentSelectResult;
            let targetUri: string = uris.toString();
            try {
              let trashUri: string = await fileManagerService.deleteToTrash(targetUri);
              console.info(`trashUri: ` + trashUri);
            } catch (err) {
              let error: BusinessError = err as BusinessError;
              console.error(`delete failed, errCode:` + error.code + `, errMessage:` + error.message);
            }
            console.info(`documentViewPicker.select to file succeed and uris are:` + uris);
          }).catch((err: BusinessError) => {
            console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
          })
        })
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中第三方应用可以读、写插入usb存储设备的doc文件吗的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你这个追问本质上是“能不能由三方应用在用户无感知的情况下直接删除 U 盘原文件”。按当前文件访问模型,这个方向通常不建议作为产品方案。

DocumentViewPicker 解决的是“用户主动选择文件后,应用可以基于返回的 URI 访问该文件”。这个 URI 默认是临时访问授权;如果要长期访问,需要走 FilePicker 的持久化授权流程,而且读、写、删除能力还要以具体 URI、设备形态和系统授权结果为准。它不等价于给普通三方应用开放 U 盘目录级文件管理权限。

可落地的方案建议分三类:

  1. 只需要处理文件内容:Picker 选择文件 -> 用 fileIo 读取 -> 复制到应用沙箱 -> 在沙箱内处理和删除。

  2. 需要回写原文件:基于用户选择的 URI 尝试按写入模式打开,失败时提示用户重新授权或改为保存副本。

  3. 需要删除 U 盘原文件或批量清理:建议让用户在系统文件管理/选择器确认删除,或者把流程改成“导入后提示用户手动清理”。ohos.permission.FILE_ACCESS_MANAGER 属于高管控能力,不适合作为普通应用的默认依赖。

因此,“读取后自动删除源文件”这类需求,权限和审核边界都会比较敏感,最好设计成用户可感知、可确认的删除流程。

使用FilePicker 持久化授权API
用户手动授权USB文档后,应用永久获得该文件读写、删除权限,完全符合鸿蒙隐私管控规范,个人应用即可上架审核
搭配PreviewKit完成doc文档预览,读取解析文件内容
调用统一文件管理接口,直接执行USB文件删除操作,无需遍历底层磁盘路径
全程遵循外接存储沙盒权限机制,不触碰系统底层路径,不会触发安全拦截
无需申请FILE_ACCESS_MANAGER系统权限
仅声明常规存储公共权限,应用商店审核100%通过
适配HarmonyOS 5/Next全版本USB OTG外设
用户手动授权单个文件,不获取全盘USB权限,隐私合规拉满
这,

普通三方应用不建议按“直接遍历 USB 路径并删除文件”设计。HarmonyOS NEXT 对公共目录/外置存储是用户授权模型:DocumentViewPicker 适合让用户主动选择文件,拿到 URI 后读或按授权写;但读取后静默删除原文件,不等价于读写授权。FILE_ACCESS_MANAGER 也不是普通应用通用权限。建议:picker 选中文档 -> 复制到应用沙箱处理 -> 若确实要删除原文件,让用户在系统文件管理/选择器支持的删除流程中确认。

可以使用 picker.DocumentSelectOptions() 去删除选择的公共文件
选择完拿到公共文件路径 再通过 File Manager Service Kit(文件管理服务) 去删除文件()

const documentSelectOptions = new picker.DocumentSelectOptions();
documentSelectOptions.fileSuffixFilters = ['.*'];
// 批量授权模式,默认为false(非批量授权模式)。当multiAuthMode为true时为批量授权模式。当multiAuthMode为true时,只有multiUriArray参数生效,其他参数不生效。该参数在Phone设备中可正常使用,在其他设备中无效果。
documentSelectOptions.multiAuthMode = false;
// 该参数在Phone设备中可正常使用,在其他设备中无效果。
documentSelectOptions.mergeMode = picker.MergeTypeMode.DEFAULT;
// 是否支持加密(仅支持文件,文件夹不生效),默认为false。该参数为true时,在Picker界面可以选择对文件进行加密。(说明:从API version 19开始支持该参数)。
documentSelectOptions.isEncryptionSupported = false;
let uris: string[] = [];
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
const documentViewPicker = new picker.DocumentViewPicker(context);
documentViewPicker.select(documentSelectOptions).then(async (documentSelectResult: string[]) => {
    let uri = documentSelectResult[0];
    this.deleteFile(uri)
}).catch((err: BusinessError) => {
    console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
});

async deleteFile(path: string) {
    try {
        let trashUri: string = await fileManagerService.deleteToTrash(path);
        console.info("删除成功 目录地址: " + trashUri);
    } catch (err) {
        let error: BusinessError = err as BusinessError;
        console.error("delete failed, errCode:" + error.code + ", errMessage:" + error.message);
    }
}

在HarmonyOS NEXT中,第三方应用可通过FilePicker(文件选择器)获取用户授权的USB存储设备访问权限,实现对doc文件的读写操作。系统要求应用声明ohos.permission.READ_EXTERNAL_STORAGEohos.permission.WRITE_EXTERNAL_STORAGE权限,且必须由用户主动授予。不支持直接通过路径访问,需使用沙箱化文件URI。

第三方应用直接读写和删除USB设备中的文件,必须通过 FileAccess 框架(fileAccess)来实现,没有其他更“取巧”的稳定办法。

DocumentViewPicker 返回的Uri通常是临时授权且只读的,不支持直接删除。你提到的 ohos.permission.FILE_ACCESS_MANAGER 其实并不难获取,它属于normal级别权限,只需在 module.json5 中声明,安装时用户授权即可,无需特殊审批。

核心实现思路是利用 @ohos.file.fileAccess 模块。你需要先通过 getFileAccessAbilityInfo 查询外部存储设备的信息,然后创建 FileAccessHelper 实例获取文件访问的根Uri,再通过 listFiledelete 等接口操作文件。简要代码示例如下:

import { fileAccess } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

async function deleteFileFromUSB(context: common.Context) {
  try {
    // 1. 获取外置存储(USB)的访问辅助类
    let fileAccessHelper = fileAccess.createFileAccessHelper(context);
    // 获取USB设备的根Uri,实际开发中可通过getFileAccessAbilityInfo遍历查找
    let rootInfos = await fileAccessHelper.getRoots();
    // 假设找到U盘的标示是"ext"类型,此处仅为逻辑示例
    let usbRootUri = rootInfos[0].uri;

    // 2. 列出文件
    let fileInfos = await fileAccessHelper.listFile(usbRootUri, {});
    // 找到需要删除的doc文件,假设文件名是 target.doc
    let targetFileUri = fileInfos[0].uri + "/" + "target.doc";

    // 3. 删除文件
    await fileAccessHelper.delete(targetFileUri);
  } catch (error) {
    let err = error as BusinessError;
    console.error(`操作失败,错误码: ${err.code}, 信息: ${err.message}`);
  }
}

delete 接口需要基于 FileAccess 框架返回的Uri,无法直接使用 DocumentViewPicker 获取的Uri拼接。

回到顶部