更新记录

0.1.0(2026-05-14) 下载此版本

更新日志

0.1.0

  • 初版创建 filekit-picker UTS 插件目录结构
  • 新增 pickFile(options)copyToSandbox(options)pickAndCopyToSandbox(options) Promise API
  • 新增 PickFileOptionsPickedFileItemCopySourceItemCopyToSandboxOptionsSandboxFileItemPickFileError 等类型定义
  • Android 端基于 ACTION_OPEN_DOCUMENT 实现系统文件选择能力
  • 支持单选 / 多选、maxCount 数量限制、mimeTypes 过滤
  • 支持返回标准文件元数据,包括文件名、大小、MIME、扩展名、最后修改时间
  • 支持将 content:// 与本地文件路径复制到应用沙盒目录
  • 支持 _doc_documents_downloads_www 等目标根目录与自定义子目录
  • 支持 renamereplaceerror 三种重名策略
  • 支持 useTempFilePath: true,可复制到临时上传路径并配合 uni.uploadFile 使用
  • 新增根工程演示页与 utssdk-test 自测页
  • 新增上传演示链路与 tempFilePath 返回结果展示

平台兼容性

uni-app(4.25)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × × 10.0 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

filekit-picker

在 uni-app App Android 场景下选择手机文件,并按需复制到应用沙盒目录或临时上传路径的 UTS 插件。

简介

filekit-picker 首版专注解决两类问题:

  • 通过 Android 系统文件选择器选择手机中的文件
  • 将选择结果按需复制到应用沙盒目录,或复制到临时路径后直接用于上传

当前实现基于 Android ACTION_OPEN_DOCUMENT,适合 uni-app App Android 场景下的附件选择、文件发送、业务文件导入、上传前转存、内容 URI 转本地路径等需求。

当前支持

  • 平台:App-Android
  • HBuilderX 建议最低版本:4.25+
  • Android 端已实现:pickFile / copyToSandbox / pickAndCopyToSandbox
  • API 风格:Promise
  • 文件选择:支持单选 / 多选
  • 文件数量限制:支持 maxCount
  • MIME 过滤:支持 mimeTypes
  • 复制目标:支持 _doc / _documents / _downloads / _www 及相对子目录
  • 上传临时路径:支持 useTempFilePath: true
  • 重名策略:rename / replace / error
  • 返回结果:支持标准文件元数据、sandboxPathtempFilePath

兼容性说明

  • HBuilderX
    • 建议使用 4.25 或更高版本进行 UTS 插件开发、调试和打包
  • Android
    • 当前实现仅提供 App-Android
    • 文件选择基于系统 ACTION_OPEN_DOCUMENT
    • 沙盒复制支持内容 URI 和本地文件路径
  • iOS
    • 当前未提供实现

系统权限说明

插件本身需要的系统权限

当前版本插件本身不要求额外申请传统 Android 存储读写权限

原因:

  • 文件选择基于系统文档选择器 ACTION_OPEN_DOCUMENT
  • 读取文件依赖系统授予的 URI 访问能力
  • 复制目标为应用沙盒目录或应用缓存目录
  • 当前实现不依赖传统外部存储直接路径读写方式

当前权限结论

  • READ_EXTERNAL_STORAGE:插件本身通常不要求主动申请
  • WRITE_EXTERNAL_STORAGE:插件本身不要求
  • MANAGE_EXTERNAL_STORAGE:插件本身不要求,也不建议申请

需要区分的上游场景

虽然插件本身不要求额外存储权限,但业务侧在“文件来源”阶段,仍可能依赖其他系统权限或系统能力:

  • 文件来自相机、相册、录音等能力时
    • 是否需要相关权限,取决于上游业务 API
  • 文件来自远程下载时
    • 需要网络能力,但这是上游下载链路需求,不是本插件选择/复制能力本身的要求
  • 文件上传到业务服务器时
    • 需要网络能力与上传接口,不是本插件文件选择能力本身的要求

插件市场/接入文档建议表述

本插件当前版本基于 Android 系统文档选择器 ACTION_OPEN_DOCUMENT 实现文件选择能力,并支持将内容 URI 复制到应用沙盒目录或临时上传路径。插件本身不要求额外申请传统 Android 存储读写权限。
如业务上游涉及拍照、录音、相册、远程下载、文件上传等能力,请按对应 uni-app API 的要求申请相关权限或配置网络能力。

不在当前范围内

  • iOS 实现
  • Android 端文件打开能力封装
  • Android 9 及以下兼容分支专项适配
  • 业务上传接口封装
  • 业务提示 UI
  • 权限引导页面

适用场景

  • 类似聊天场景中选择手机文件并发送
  • 选择 PDF、图片、Office、视频等文件后复制到应用沙盒
  • content:// 文件复制为本地可读写路径
  • 选择后直接复制到临时路径并调用 uni.uploadFile
  • 对导入文件做缓存、副本保存、后续解析处理

安装方式

将插件放入项目 uni_modules 目录。

uni_modules/
└─ filekit-picker/

然后在页面中直接引入:

import { pickFile, copyToSandbox, pickAndCopyToSandbox } from '@/uni_modules/filekit-picker'

API

pickFile(options)

选择文件。

pickFile(options: PickFileOptions): Promise<PickFileResult>

copyToSandbox(options)

将内容 URI 或本地文件路径复制到应用沙盒目录或临时上传路径。

copyToSandbox(options: CopyToSandboxOptions): Promise<CopyToSandboxResult>

pickAndCopyToSandbox(options)

先选择文件,再复制到应用沙盒目录或临时上传路径。

pickAndCopyToSandbox(options: PickAndCopyToSandboxOptions): Promise<PickAndCopyToSandboxResult>

类型定义

PickFileOptions

type PickFileOptions = {
  multiple?: boolean
  maxCount?: number
  mimeTypes?: string[]
  copyToSandbox?: boolean
  useTempFilePath?: boolean
  sandboxRoot?: string
  sandboxDir?: string
  conflictStrategy?: 'rename' | 'replace' | 'error'
}

参数说明

  • multiple
    • 可选
    • 是否允许多选
  • maxCount
    • 可选
    • 多选模式下允许的最大文件数量
  • mimeTypes
    • 可选
    • 例如 ['image/*', 'application/pdf']
  • copyToSandbox
    • 可选
    • true 时,pickFile 结束后自动执行复制
  • useTempFilePath
    • 可选
    • true 时优先复制到应用缓存目录,返回 tempFilePath
    • 适合“选择后直接上传”的链路
  • sandboxRoot
    • 可选
    • 支持 _doc / _documents / _downloads / _www
  • sandboxDir
    • 可选
    • 目标子目录,例如 chat-files
  • conflictStrategy
    • 可选,默认建议使用 rename
    • rename:同名自动重命名
    • replace:覆盖已有同名文件
    • error:遇到同名文件直接报错

PickedFileItem

type PickedFileItem = {
  uri: string
  displayName: string
  size: number
  mimeType: string
  extension?: string
  lastModified?: number
  sourceType: string
  sandboxPath?: string
  tempFilePath?: string
}

CopySourceItem

type CopySourceItem = {
  uri?: string
  path?: string
  fileName?: string
  mimeType?: string
}

CopyToSandboxOptions

type CopyToSandboxOptions = {
  files: CopySourceItem[]
  useTempFilePath?: boolean
  sandboxRoot?: string
  sandboxDir?: string
  conflictStrategy?: 'rename' | 'replace' | 'error'
}

SandboxFileItem

type SandboxFileItem = {
  sourceUri?: string
  sourcePath?: string
  fileName: string
  size: number
  mimeType: string
  sandboxDir: string
  sandboxPath: string
  tempFilePath?: string
}

PickFileResult

type PickFileResult = {
  success: boolean
  files: PickedFileItem[]
  count: number
  message?: string
}

CopyToSandboxResult

type CopyToSandboxResult = {
  success: boolean
  files: SandboxFileItem[]
  count: number
  message?: string
}

PickAndCopyToSandboxResult

type PickAndCopyToSandboxResult = {
  success: boolean
  files: SandboxFileItem[]
  count: number
  message?: string
}

PickFileError

type PickFileError = {
  code: string
  message: string
  detail?: string
}

使用示例

示例 1:选择文件

import { pickFile } from '@/uni_modules/filekit-picker'

const result = await pickFile({
  multiple: true,
  maxCount: 3,
  mimeTypes: ['image/*', 'application/pdf']
})

console.log(result.files)

示例 2:选择后复制到 _doc/chat-files

import { pickAndCopyToSandbox } from '@/uni_modules/filekit-picker'

const result = await pickAndCopyToSandbox({
  multiple: true,
  maxCount: 5,
  mimeTypes: ['*/*'],
  sandboxRoot: '_doc',
  sandboxDir: 'chat-files',
  conflictStrategy: 'rename'
})

console.log(result.files)

示例 3:选择后复制到临时路径并上传

import { pickAndCopyToSandbox } from '@/uni_modules/filekit-picker'

const pickResult = await pickAndCopyToSandbox({
  multiple: false,
  mimeTypes: ['application/pdf'],
  useTempFilePath: true,
  conflictStrategy: 'rename'
})

const firstFile = pickResult.files[0]
if (firstFile?.tempFilePath) {
  await uni.uploadFile({
    url: 'https://example.com/upload',
    filePath: firstFile.tempFilePath,
    name: 'file'
  })
}

错误码

当前版本已规划并使用以下错误码(实际返回会按场景补充):

  • USER_CANCELLED
  • NO_FILE_SELECTED
  • MAX_COUNT_EXCEEDED
  • MIME_TYPE_NOT_ALLOWED
  • INVALID_MAX_COUNT
  • INVALID_SANDBOX_ROOT
  • INVALID_SANDBOX_DIR
  • FILE_NOT_FOUND
  • FILE_ALREADY_EXISTS
  • SANDBOX_UNAVAILABLE
  • CREATE_SANDBOX_DIR_FAILED
  • TEMP_DIR_UNAVAILABLE
  • UNSUPPORTED_PLATFORM
  • PICK_FILE_FAILED
  • COPY_TO_SANDBOX_FAILED

注意事项

1. content:// 不建议直接交给 uni.uploadFile

系统文件选择器返回的 uri 通常是内容 URI,不建议直接作为上传路径使用。

建议做法:

  • 复制到沙盒目录后使用 sandboxPath
  • 或复制到临时路径后使用 tempFilePath

2. _www 在部分环境下可能不可写

虽然插件支持传入 _www,但实际业务中更建议优先使用:

  • _doc
  • _documents
  • _downloads

3. 临时路径适合上传,不适合长期持久化

传入 useTempFilePath: true 时,文件会被复制到应用缓存目录,适合上传、解析、短期使用。 如需长期保存,请复制到 _doc 等持久目录。

4. 多选数量限制由插件结果阶段校验

即使系统文件选择器允许多选,插件仍会根据 maxCount 对最终结果做数量校验。

实现说明

当前 Android 实现主要基于:

  • Intent.ACTION_OPEN_DOCUMENT
  • Intent.EXTRA_ALLOW_MULTIPLE
  • Intent.EXTRA_MIME_TYPES
  • ContentResolver.query()
  • ContentResolver.openInputStream()
  • 应用沙盒目录 / 应用缓存目录文件复制

这种方式更适合 Android 上对系统文件选择与内容 URI 读取的规范访问方式。

调试建议

  • 优先先测单文件选择,再测多文件选择
  • 先验证图片 / PDF,再测 Office / 视频等类型
  • 上传链路请优先使用 tempFilePath
  • 真机调试时重点验证中文文件名、重名策略、多选数量限制

路线图

  • 继续补充 README 与插件市场说明细节
  • 继续完善 utssdk-test 真机联调体验
  • 评估 iOS 空实现或后续支持方式
  • 评估更多文件管理配套能力

版本信息

  • 当前版本:0.1.0
  • 当前阶段:首版联调中

隐私、权限声明

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

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

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

许可协议

MIT协议

暂无用户评论。