更新记录
0.1.0(2026-05-14) 下载此版本
更新日志
0.1.0
- 初版创建
filekit-downloadsUTS 插件目录结构 - 新增
saveToDownloads(options)Promise API - 新增
SaveToDownloadsOptions、SaveToDownloadsResult、SaveToDownloadsError类型定义 - Android 端基于
MediaStore.Downloads实现保存到公共Download/<subDir>目录 - 支持
_doc/、_downloads/、_www/、tempFilePath、savedFilePath等本地文件路径 - 支持
rename、replace、error三种重名策略 - 支持按文件名后缀自动推断 MIME 类型
- 新增错误对象封装与可读错误码
- 新增项目内联调页与插件 README 初稿
平台兼容性
uni-app(4.25)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | × | 10.0 | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
filekit-downloads
将 uni-app App 端本地临时文件或私有目录文件,保存到 Android 公共 Download/<subDir> 目录的 UTS 插件。
简介
filekit-downloads 首版专注解决一个问题:
- 把
_doc/、_downloads/、_www/、uni.downloadFile返回的tempFilePath、uni.saveFile返回的savedFilePath等本地文件 - 保存到 Android 公共下载目录
Download或Download/<subDir>
当前实现基于 Android MediaStore.Downloads,适合 uni-app App Android 场景下的文件导出、附件留存、本地临时文件转存等需求。
当前支持
- 平台:
App-Android - HBuilderX 建议最低版本:
4.25+ - Android 最低版本:
29(Android 10) - API 风格:
Promise - 保存目标:
Download/Download/<subDir> - 重名策略:
rename/replace/error - MIME:支持自动推断,兜底
application/octet-stream
兼容性说明
HBuilderX- 建议使用
4.25或更高版本进行 UTS 插件开发、调试和打包 - 插件
package.json已声明engines.HBuilderX = ^4.25.0
- 建议使用
Android- 当前
utssdk/app-android/config.json已声明minSdkVersion = 29 - 即首版最低支持 Android 10
- 当前
iOS- 当前未提供实现
系统权限说明
插件本身需要的系统权限
当前版本插件本身不要求额外申请 Android 存储读写权限。
原因:
- 当前实现仅支持
Android 10+ - 插件基于
MediaStore.Downloads保存文件到公共Download目录 - 当前实现不依赖传统外部存储直接路径写入方式
- 插件最低 Android 版本为
29
当前权限结论
READ_EXTERNAL_STORAGE:插件本身不要求WRITE_EXTERNAL_STORAGE:插件本身不要求MANAGE_EXTERNAL_STORAGE:插件本身不要求,也不建议申请
需要区分的上游场景
虽然插件本身不要求额外存储权限,但业务侧在“获取源文件”阶段,仍可能依赖其他系统权限或系统能力:
- 文件来自
uni.chooseImage、相机、相册等能力时- 是否需要相机/相册相关权限,取决于上游业务 API
- 文件来自远程下载时
- 需要网络能力,但这是下载链路需求,不是本插件保存能力本身的要求
- 文件来自应用私有目录(如
_doc/、tempFilePath、savedFilePath)时- 当前插件一般可直接处理,不需要额外存储权限
插件市场/接入文档建议表述
本插件当前版本基于 Android 10+ 的 MediaStore.Downloads 实现公共 Download 目录保存能力,插件本身不要求额外申请存储读写权限。
如业务上游涉及拍照、选图、远程下载等能力,请按对应 uni-app API 的要求申请相关权限。
不在当前范围内
- iOS 实现
- Android 9 及以下兼容分支
- 远程下载能力封装
- 打开文件能力
- 业务提示 UI
- 权限引导页面
适用场景
- 将
uni.chooseImage选择后的临时文件保存到公共下载目录 - 将
uni.downloadFile下载完成后的本地文件转存到公共目录 - 将业务运行过程中生成的
_doc/文件导出给用户 - 将 PDF、图片、Office、视频等文件保存到系统可见目录
安装方式
将插件放入项目 uni_modules 目录。
uni_modules/
└─ filekit-downloads/
然后在页面中直接引入:
import { saveToDownloads } from '@/uni_modules/filekit-downloads'
API
saveToDownloads(options)
将本地文件保存到 Android 公共 Download 目录。
saveToDownloads(options: SaveToDownloadsOptions): Promise<SaveToDownloadsResult>
SaveToDownloadsOptions
type SaveToDownloadsOptions = {
srcPath: string
fileName: string
mimeType?: string
subDir?: string
conflictStrategy?: 'rename' | 'replace' | 'error'
scanImmediately?: boolean
}
参数说明
srcPath- 必填
- 本地文件路径,必须是文件,不能是目录
- 支持
_doc/、_downloads/、_www/、tempFilePath、savedFilePath等
fileName- 必填
- 保存到下载目录后的文件名,例如
test.jpg、合同.pdf
mimeType- 可选
- 不传时按文件名后缀自动推断
subDir- 可选
- 例如传
MyAppFile,实际保存到Download/MyAppFile
conflictStrategy- 可选,默认建议使用
rename rename:同名自动重命名replace:删除已有同名文件后保存error:遇到同名文件直接报错
- 可选,默认建议使用
scanImmediately- 预留字段
- 当前版本暂未启用额外扫描逻辑
SaveToDownloadsResult
type SaveToDownloadsResult = {
success: boolean
fileName: string
mimeType: string
relativePath: string
contentUri: string
absolutePath?: string
message?: string
}
返回值说明
success- 是否保存成功
fileName- 最终保存的文件名
mimeType- 最终使用的 MIME 类型
relativePath- 例如
Download、Download/MyAppFile
- 例如
contentUri- Android 10+ 下的结果标识
absolutePath- 可选,不保证所有系统环境都稳定返回
message- 简单结果描述
SaveToDownloadsError
type SaveToDownloadsError = {
code: string
message: string
detail?: string
}
使用示例
示例 1:选择图片后保存
<script setup>
import { ref } from 'vue'
import { saveToDownloads } from '@/uni_modules/filekit-downloads'
const tempFilePath = ref('')
const fileName = ref('')
const buildFileName = (filePath) => {
const normalized = (filePath || '').split('?')[0]
const dotIndex = normalized.lastIndexOf('.')
const ext = dotIndex >= 0 ? normalized.slice(dotIndex) : '.jpg'
return `image-${Date.now()}${ext}`
}
const chooseAndSave = () => {
uni.chooseImage({
count: 1,
sizeType: ['original'],
success: async (res) => {
tempFilePath.value = res.tempFilePaths[0] || ''
fileName.value = buildFileName(tempFilePath.value)
try {
const result = await saveToDownloads({
srcPath: tempFilePath.value,
fileName: fileName.value,
subDir: 'MyAppFile',
conflictStrategy: 'rename'
})
console.log('保存成功', result)
} catch (err) {
console.error('保存失败', err)
}
}
})
}
</script>
示例 2:uni.downloadFile 成功后再保存
import { saveToDownloads } from '@/uni_modules/filekit-downloads'
const downloadUrl = 'https://example.com/demo.pdf'
uni.downloadFile({
url: downloadUrl,
success: async (res) => {
if (res.statusCode !== 200) {
console.error('下载失败', res)
return
}
if (!res.tempFilePath || res.tempFilePath.endsWith('/')) {
console.error('无效临时文件路径', res.tempFilePath)
return
}
try {
const result = await saveToDownloads({
srcPath: res.tempFilePath,
fileName: 'demo.pdf',
subDir: 'MyDownload',
conflictStrategy: 'rename'
})
console.log('保存成功', result)
} catch (err) {
console.error('保存失败', err)
}
},
fail: (err) => {
console.error('下载接口调用失败', err)
}
})
错误码
当前版本已规划并使用以下错误码:
INVALID_SRC_PATHFILE_NOT_FOUNDINVALID_FILE_NAMEINSERT_MEDIASTORE_FAILEDOPEN_OUTPUT_STREAM_FAILEDCOPY_STREAM_FAILEDUNSUPPORTED_PLATFORMFILE_ALREADY_EXISTS
注意事项
1. srcPath 必须是文件路径
以下情况不能直接传给插件:
- 目录路径
- 下载临时目录
- 末尾带
/的路径
例如:
_doc/uniapp_temp_xxx/download/
这是目录,不是实际文件。
2. uni.downloadFile 的 success 不等于业务下载成功
uni.downloadFile 进入 success 回调时,仍然需要判断:
res.statusCode === 200res.tempFilePath是有效文件路径
如果返回:
{
"statusCode": 400,
"errMsg": "downloadFile:ok"
}
说明下载接口流程返回成功,但服务端拒绝了该请求,不能继续保存。
3. 常见的 HTTP 400 原因
- 下载地址需要鉴权,但请求未带
token/cookie/ 签名参数 - 下载 URL 已过期
- 下载地址不是直链文件地址
- 服务端对请求头有要求
- 服务端对来源或参数有校验
4. 文件名建议由业务层明确提供
虽然插件支持 MIME 自动推断,但仍建议业务层传入明确的 fileName,这样更利于:
- 用户在下载目录中识别文件
- 保证后缀正确
- 控制重名策略行为
实现说明
当前 Android 实现基于 MediaStore.Downloads:
- 写入
DISPLAY_NAME - 写入
MIME_TYPE - 写入
RELATIVE_PATH - 使用
IS_PENDING控制写入状态 - 通过
ContentResolver.openOutputStream()写入文件内容
这种方式更符合 Android 10+ 公共存储访问规范。
调试建议
- 优先先测本地图片保存链路,再测远程下载后保存链路
- 先验证
tempFilePath是否为真实文件路径 - 如下载返回非
200,先独立排查服务端下载地址 - 如要测试远程下载,建议先用公开可访问的直链文件验证插件链路
路线图
- 补齐
utssdk-test标准自测结构 - 补齐插件市场文档材料
- 评估 Android 9 及以下兼容方案
- 评估 iOS 空实现或后续支持方式
版本信息
- 当前版本:
0.1.0 - 当前阶段:首版联调中

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 0
赞赏 0
下载 11912408
赞赏 1914
赞赏
京公网安备:11010802035340号