Ionic结合Capacitor使用Native file transfer插件在安卓10/11无法创建目录
你遇到的报错是Android 7之后系统存储权限规则变更导致的,Android 10(API 29)正式引入分区存储机制,禁止第三方应用直接读写外部存储根目录的自定义路径,你代码中写死的file:///storage/emulated/0/Universal-Book/路径在Android 7以上版本无法被普通应用直接访问,同时旧版Native File Transfer插件已经停止维护,未适配新的系统存储规则,因此触发PATH_EXISTS_ERR和下载失败问题。
解决方案
1. 调整安卓权限配置
在项目的android/app/src/main/AndroidManifest.xml中添加适配配置:
- 在
<application>标签中添加属性兼容Android 10:<application android:requestLegacyExternalStorage="true" ...其他原有属性 > - 添加对应存储权限:
<!-- 安卓9及以下读写权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- 安卓13及以上媒体文件权限,非媒体文件可根据需求申请MANAGE_EXTERNAL_STORAGE(需谷歌商店审核说明用途) --> <uses-permission android:name="android.permission.READ_MEDIA_EPUB" />
2. 修改存储路径规则
不要硬写外部存储根目录的自定义路径,改用系统提供的公共目录:
- 如果需要下载的文件对用户可见,优先使用系统公共下载目录、文档目录,不要自行在根目录创建
Universal-Book文件夹 - 如果你使用Capacitor官方插件,直接调用
Directory.Downloads或Directory.Documents枚举值即可自动适配不同版本的系统路径
3. 替换已停止维护的插件
Native File Transfer插件已多年未更新,建议直接使用Capacitor官方维护的@capacitor/filesystem插件实现下载功能,原生适配所有安卓版本的存储规则,示例代码如下:
import { Filesystem, Directory, DownloadFileOptions } from '@capacitor/filesystem'; const downloadEpub = async (fileUrl: string, fileName: string) => { // 先判断文件是否已存在,按需处理覆盖/重命名逻辑 try { await Filesystem.stat({ path: fileName, directory: Directory.Downloads }); // 文件已存在逻辑,可提示用户是否覆盖,或自动重命名 const confirmCover = true; // 这里可替换为你的交互逻辑 if (!confirmCover) { fileName = `${Date.now()}_${fileName}`; } } catch (e) { // 文件不存在,直接下载 } const options: DownloadFileOptions = { url: fileUrl, path: fileName, directory: Directory.Downloads, replace: true, // 开启覆盖已存在文件,避免PATH_EXISTS_ERR报错 progress: true }; const downloadResult = await Filesystem.downloadFile(options); if (downloadResult.path) { // 下载成功逻辑 } }
4. 冲突异常处理
如果业务逻辑不允许覆盖已存在文件,可在下载前先调用文件查询接口判断目标路径是否存在文件,存在的话给文件名添加时间戳、序号等后缀后再执行下载,即可避免路径存在报错。
内容的提问来源于stack exchange,提问作者kuldeep kush
相关产品推荐
相关产品推荐

