uni-app uni.saveFile 在 Android11 保存失败 targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径

uni-app uni.saveFile 在 Android11 保存失败 targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径

产品分类:

uniapp/App

PC开发环境操作系统:

Windows

PC开发环境操作系统版本号:

Windows 10 专业版

HBuilderX类型:

正式

HBuilderX版本号:

3.1.22

手机系统:

Android

手机系统版本号:

Android 11

手机厂商:

OPPO

手机机型:

Reno6 5g

页面类型:

vue

打包方式:

云端

项目创建方式:

HBuilderX

示例代码:

saveFiles() {
    let _this = this
    uni.chooseImage({
        count: 1,
        extension: ['.png', '.jpg'], // app下不起作用
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album', 'camera'], //图片来源
        success: function(res) {
            console.log('图片', res)
            _this.$toast('图片' + JSON.stringify(res))
            res.tempFilePaths.map(f => {
                uni.saveFile({
                    tempFilePath: f,
                    complete: (e) => {
                        console.log('转储结果', e)
                        _this.$toast('转储结果' + JSON.stringify(e))
                    }
                })
            })
        }
    })
}

操作步骤:

使用uni.chooseImage选择图片,然后调用uni.saveFile 将选择的图片转储。

预期结果:

期望3张图片通过uni.saveFile可以正常转储

实际结果:

{
    "errMsg": "chooseImage:ok",
    "tempFilePaths": ["file:///storage/emulated/0/Pictures/WeiXin/mmexport1626358388425.jpg"],
    "tempFiles": [{
        "path": "file:///storage/emulated/0/Pictures/WeiXin/mmexport1626358388425.jpg",
        "size": 470484
    }]
}
{
    "errMsg": "saveFile:fail targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199",
    "errCode": 15,
    "code": 15
}
{
    "errMsg": "chooseImage:ok",
    "tempFilePaths": ["file:///storage/emulated/0/Pictures/WeiXin/IMG_20210715_221750.jpg"],
    "tempFiles": [{
        "path": "file:///storage/emulated/0/Pictures/WeiXin/IMG_20210715_221750.jpg",
        "size": 496404
    }]
}
{
    "errMsg": "saveFile:fail targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199",
    "errCode": 15,
    "code": 15
}
{
    "errMsg": "chooseImage:ok",
    "tempFilePaths": ["_doc/uniapp_temp_1628235046888/compressed/1628235106969_mmexport1626358399799.jpg"],
    "tempFiles": [{
        "path": "_doc/uniapp_temp_1628235046888/compressed/1628235106969_mmexport1626358399799.jpg",
        "size": 110499
    }]
}
{
    "errMsg": "saveFile:ok",
    "savedFilePath": "_doc/uniapp_save/16282351071964.jpg"
}

bug描述:

使用uni.chooseImage可以正常选择图片, 然后使用uni.saveFile保存, 有的图片是可以保存的, 但是有的图片提示:

{
    "code": 15,
    "message": "targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199"
}

Image 1

Image 2

Image 3

Pictures.rar


更多关于uni-app uni.saveFile 在 Android11 保存失败 targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

HX什么版本呢 理论上3.1.22应该没有这个问题才对

更多关于uni-app uni.saveFile 在 Android11 保存失败 targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径的实战教程也可以访问 https://www.itying.com/category-93-b0.html


3.1.22.20210709版本

我提供的图可以试一下

回复 火柴123: 真机基座复现吗 。请提供一些测试demo我们复现一些 如果确定是bug会尽快修复

回复 火柴123: 不能保存到地址发下

真机基座调试的, 今天试了下视频保存也有这种问题。 保存地址就是用的uni.SaveFile默认的地址,应该是保存在了_doc/uniapp_save 文件夹下。 请看示例代码, 我测试用的就是这个代码。

回复 火柴123: 问题已确认会尽快修复

真机基座调试的, 今天试了下视频保存也有这种问题。 保存地址就是用的uni.SaveFile默认的地址,应该是保存在了_doc/uniapp_save 文件夹下。 请看示例代码, 我测试用的就是这个代码。

HX3.2.1 alpha已修复该问题

辛苦了! 正式版本什么时候发布呢

这个问题是由于Android 10(API 29)及以上版本的存储权限策略变更导致的。当targetSdkVersion设置为29或更高时,应用无法直接访问外部存储的公共目录(如/storage/emulated/0/Pictures/WeiXin/),只能访问应用专属目录或通过MediaStore API访问媒体文件。

从你的错误信息可以看出:

  1. uni.chooseImage返回的路径是外部存储公共目录(如file:///storage/emulated/0/Pictures/WeiXin/)时,uni.saveFile会失败。
  2. 当返回的路径是应用私有目录(如_doc/uniapp_temp_...)时,uni.saveFile可以成功。

解决方案:

  1. 使用uni.downloadFile替代(推荐): 如果是从网络下载文件,直接使用uni.downloadFile,它会自动保存到应用私有目录。

  2. 使用uni.getFileSystemManager()处理本地文件: 对于本地文件操作,可以使用文件系统API将文件复制到应用私有目录:

    const fs = uni.getFileSystemManager();
    const tempPath = res.tempFilePaths[0];
    const savedPath = `${uni.env.USER_DATA_PATH}/${Date.now()}.jpg`;
    
    fs.copyFile({
        srcPath: tempPath,
        destPath: savedPath,
        success: () => {
            console.log('文件保存成功', savedPath);
        }
    });
    
  3. 配置Android权限(临时方案): 在manifest.json中添加:

    {
        "app-plus": {
            "distribute": {
                "android": {
                    "permissions": [
                        "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
                        "<uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>"
                    ]
                }
            }
        }
    }
回到顶部