更新记录

1.0.0(2026-08-06)

支持ios及安卓端的文件选择插件


平台兼容性

ybt-file-picker

ybt-file-picker 是一个 App 端 UTS 文件选择插件。插件会打开系统文件选择器,将用户选择的文件复制到应用缓存目录,并返回可用于上传的 file:// 本地路径。

功能特点

  • 支持单选和多选,并可通过 count 限制本次最多处理的文件数。
  • 支持选择图片、音频、视频、PDF、OFD 及其他普通文件。
  • 选择结果会复制到应用缓存目录,避免业务层直接处理 Android content:// 地址或 iOS 安全作用域文件。
  • 返回结构兼容 uni.chooseFile 的常用字段:tempFilestempFilePaths
  • 单个文件同时提供 pathfilePathtempFilePathuri 路径别名,方便对接现有上传逻辑。
  • 提供统一的 successfailcomplete 回调和错误码。

平台支持

平台 支持情况 最低版本/说明
Android App 支持 Android 5.0(API 21)及以上
iOS App 支持 iOS 12.0 及以上
HarmonyOS App 暂不支持 调用后通过 fail 返回 9010001
H5、小程序 不支持 请使用对应平台的 uni.chooseFile 等 API

插件 package.json 声明的最低开发环境为 HBuilderX 3.6.8、uni-app/uni-app x 3.1.0。这是 App 原生插件;新增插件或修改原生代码后,如果标准运行基座未包含该插件,需要重新制作自定义调试基座或重新打包。

快速使用

插件放在项目的 uni_modules/ybt-file-picker 目录后,可直接导入,无需全局注册。

// 仅在 App 端导入,避免 H5、小程序构建时引用 App 原生插件
// #ifdef APP-PLUS
import { chooseFile as ybtChooseFile } from '@/uni_modules/ybt-file-picker'
// #endif

function selectFiles() {
  // #ifdef APP-PLUS
  ybtChooseFile({
    count: 3,
    title: '选择附件',
    // 当前版本不会按 extensions 过滤,仍需在 success 中自行校验
    extensions: ['pdf', 'ofd'],
    success: (res) => {
      console.log('选择成功', res.tempFiles)
      console.log('文件路径', res.tempFilePaths)
    },
    fail: (err) => {
      // 用户主动取消通常无需提示错误
      if (err.errCode !== 9010002) {
        uni.showToast({
          title: err.errMsg || '选择文件失败',
          icon: 'none'
        })
      }
    },
    complete: (res) => {
      console.log('文件选择结束', res)
    }
  })
  // #endif
}

API

chooseFile(options)

打开系统文件选择器。该方法没有 Promise 返回值,请通过回调接收结果。

chooseFile(options: ChooseFileOptions): void

options 参数

参数 类型 必填 默认值 说明
count number 1 最多处理的文件数。小于 1 时按 1 处理;系统文件选择器本身也可能限制实际可选数量
title string 选择文件 系统选择器标题。Android 会将其用于 chooser 标题;iOS 当前不会展示自定义标题
extensions string[] - 预留的扩展名列表。当前 Android、iOS 实现均不会据此过滤,业务层必须自行校验
success (res) => void - 所有已选文件成功复制到缓存后触发
fail (err) => void - 选择器打开失败、用户取消或文件读取失败时触发
complete (res) => void - 无论成功或失败都会触发;参数与对应的 successfail 参数相同

count > 1 时插件会请求系统开启多选,但具体文件管理器可能不支持多选。即使系统返回了更多文件,插件也只处理前 count 个。

success 返回值

type ChooseFileSuccess = {
  errMsg?: string
  files: ChooseFileItem[]
  tempFiles: ChooseFileItem[]
  tempFilePaths: string[]
}
字段 类型 说明
errMsg string 成功时固定为 chooseFile:ok
files ChooseFileItem[] 文件信息数组
tempFiles ChooseFileItem[] files 的兼容别名
tempFilePaths string[] 由每个文件的 path 组成的路径数组

单个文件字段

字段 类型 说明
path string 缓存文件的 file:// 本地路径,可用于后续上传
filePath string path 的别名
tempFilePath string path 的别名
uri string path 的别名;返回的是缓存文件地址,不是 Android 原始 content:// 地址
name string 原始文件名;路径分隔符、反斜杠和冒号会被替换为下划线
size number 缓存文件的实际大小,单位为字节
mimeType string 文件 MIME 类型。个别文件提供方可能无法返回准确类型
type string 按 MIME 类型归类为 imagevideoaudiofile

为了避免同名文件互相覆盖,实际缓存文件名会自动增加时间戳和 UUID;业务展示文件名时应使用 name,不要从 path 中截取。

错误处理

失败回调参数包含以下主要字段:

type ChooseFileFail = {
  errSubject: 'ybt-file-picker'
  errCode: 9010001 | 9010002 | 9010003
  errMsg: string
}
错误码 默认文案 常见原因
9010001 文件选择器打开失败 当前 Activity 不存在、系统选择器无法启动、已有选择任务尚未结束,或在暂未实现的 HarmonyOS 端调用
9010002 用户取消选择 用户返回/取消,或系统没有返回任何文件
9010003 文件读取失败 无法读取原文件、无法写入缓存、缓存文件为空,或多选中的任一文件复制失败

一次只能进行一个文件选择任务。在上一次调用结束前再次调用 chooseFile,新调用会返回 9010001。多选时只有全部文件都复制成功才会触发 success

文件类型校验

extensions 当前只是为了保持调用参数语义而保留,系统选择器仍会展示所有可打开的文件。可在成功回调中按文件名进行不区分大小写的校验:

const allowedExtensions = new Set(['pdf', 'ofd'])

function getExtension(fileName = '') {
  const cleanName = fileName.split('?')[0].split('#')[0]
  const index = cleanName.lastIndexOf('.')
  return index >= 0 ? cleanName.slice(index + 1).toLowerCase() : ''
}

ybtChooseFile({
  count: 3,
  extensions: [...allowedExtensions],
  success: (res) => {
    const invalidFile = res.tempFiles.find(
      file => !allowedExtensions.has(getExtension(file.name))
    )

    if (invalidFile) {
      uni.showToast({
        title: `不支持 ${invalidFile.name} 的文件格式`,
        icon: 'none'
      })
      return
    }

    res.tempFiles.forEach(uploadSelectedFile)
  }
})

上传示例

选择成功后,可以直接把 path 传给 uni.uploadFile

function uploadSelectedFile(file) {
  uni.uploadFile({
    url: 'https://example.com/api/upload',
    filePath: file.path,
    name: 'file',
    formData: {
      originalName: file.name
    },
    success: (res) => {
      console.log('上传成功', res)
    },
    fail: (err) => {
      console.error('上传失败', err)
    }
  })
}

缓存与权限说明

  • Android 使用系统 ACTION_OPEN_DOCUMENT,iOS 使用系统文档选择器。插件本身通常不需要申请全盘存储权限。
  • Android 会优先复制到 uni-app 提供的 App 缓存路径下的 ybt_file_picker 目录;iOS 会复制到临时目录下的 ybt_file_picker 目录。
  • 返回的是缓存文件,不应作为永久文件保存。系统可能清理缓存,建议选择成功后尽快上传;如需长期保留,请由业务层另行保存。
  • 当前插件没有提供缓存清理 API。频繁选择大文件时,业务侧应结合应用策略管理缓存占用。
  • 0 字节文件会按读取失败处理,并返回 9010003

注意事项

  • 不要并发调用 chooseFile
  • mimeType 由系统文件提供方或文件扩展名推断,业务安全校验不能只依赖该字段。
  • extensions 不等同于安全校验。上传接口仍应在服务端校验文件后缀、MIME、文件内容和大小。
  • 各品牌 Android 系统文件管理器的多选入口和交互可能不同,最终返回数量以 res.tempFiles.length 为准。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。