uni-app在app端无法用uni.choosefile唤起系统文件管理器,android需调用action_get_content或action_open_document原生intent,ios需用uidocumentpickerviewcontroller;返回uri须解析为真实路径才能使用。

uni-app 在 App 端无法用 uni.chooseFile 唤起真正的系统文件管理器(比如 Android 的“文件”App 或 iOS 的“文件”App),它默认只打开相册/相机 —— 这是绝大多数开发者踩坑的起点。
Android 端必须用 ACTION_GET_CONTENT 或 ACTION_OPEN_DOCUMENT
Android 上 uni.chooseFile 的 type: 'file' 仍走媒体库路径,选不到 PDF、TXT、CSV 等非媒体文件。真要选任意文件,得手动调原生 Intent:
-
ACTION_GET_CONTENT更轻量,适合单次选择,返回content://URI,兼容性好(支持 Android 4.0+) -
ACTION_OPEN_DOCUMENT支持多选(需加Intent.EXTRA_ALLOW_MULTIPLE)、可访问 SAF(Storage Access Framework)目录,但最低要求 Android 4.4(KitKat) - 务必调用
intent.addCategory(Intent.CATEGORY_OPENABLE),否则部分 ROM(如华为 EMUI)可能不显示文件 - 设置 MIME 类型时,
intent.setType("application/pdf")比"*/*"更精准,能过滤掉不相关文件类型 - 返回的
data.getData()是 URI,不是真实路径;plus.android.resolveNativeUri(uri)(HBuilderX 3.9.12+)可直接转为本地路径,旧版本需自己解析 Document URI
iOS 端只能用 UIDocumentPickerViewController
iOS 没有全局“文件管理器”,uni.chooseFile 在 iOS App 端也仅限照片/视频。要选其他文件,唯一合规方式是调用 UIDocumentPickerViewController:
- 必须在
manifest.json → iOS → 权限配置中添加NSDocumentPickerUsageDescription字符串,仅此一项有效 ——NSPhotoLibraryUsageDescription不管用 - 首次调用会弹系统权限框,若未配置描述字段,调用静默失败,控制台无报错
- 选中的文件返回的是临时 URL(
file://),可直接用于uni.uploadFile或uni.getFileSystemManager().readFile - 不支持直接访问 iCloud Drive 根目录,用户只能从“我的 iPhone”、“iCloud Drive”等已授权位置中选取
拿到文件后不能直接用 uni.readFile
uni.readFile 只认 tempFilePath(来自 uni.downloadFile 或 uni.uploadFile),对原生返回的路径(如 /data/user/0/... 或 file://)会报 no permission 或读出空内容:
- App 端优先用
uni.getFileSystemManager().readFile,它支持原生路径,且无需额外权限声明 - 更底层可用
plus.io.resolveLocalFileSystemURL,绕过 JS 层权限校验,尤其适合读二进制流上传 - 读取时务必指定
encoding:传二进制给后端用enc: 'base64',读文本用enc: 'utf8',否则中文乱码或解析失败
别指望 H5 的 <input type="file"> 在 App 里生效
在 App 环境下注入 <input type="file"> 并触发 click(),多数 WebView(尤其是 Android 的 X5 内核)会直接忽略或报 Not allowed to navigate top frame to data URL:
- 该方式仅在 H5 平台可靠;App 端必须走原生路径,没有“兼容写法”
- 有人尝试用
render.js注入 input,但依赖 WebView 行为,不同厂商 ROM 兼容性极差,上线后容易集体失效 - 如果项目同时要支持 H5 和 App,建议用条件编译:
#ifdef H5走 input,#ifndef H5走 plus.android / UIDocumentPicker
真正麻烦的不是调起界面,而是 URI 解析、路径转换、跨平台回调统一和二进制读取 —— 这些环节任何一个出错,都会导致“选了文件却传不上去”。











