uni-app中uni.chooseVideo()在Android端返回的物理文件路径导致uni.uploadFile()上传文件失败

uni-app中uni.chooseVideo()在Android端返回的物理文件路径导致uni.uploadFile()上传文件失败

开发环境 版本号 项目创建方式
Windows 7 旗舰版 3.1.11 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:Windows 7 旗舰版

HBuilderX类型:正式

HBuilderX版本号:3.1.11

手机系统:Android

手机系统版本号:Android 6.0

手机厂商:HTC

手机机型:M8

页面类型:vue

打包方式:云端

项目创建方式:HBuilderX

示例代码:
```cpp
videoFile:{file:{},filePath:'',fileName:String},
//选择视频文件
chooseVideo(){
var _this = this
uni.chooseVideo({
count:2,
sourceType: ['camera', 'album'],
success:function(res){
console.log("chooseVideo success ="+JSON.stringify(res))  
var fileName = ''         
if(res.name === undefined){  
     fileName =  _this.getNameFromFilePath(res.tempFilePath);  
    console.log("undefined fileName ="+fileName);  
}else {  
    fileName = new String(res.name);  
    console.log(" fileName ="+fileName);  
}  
_this.videoFile = {file: res.tempFile,filePath:res.tempFilePath,fileName:((new String(fileName)).split(".")[0])}  
 console.log("_this.videoFile ="+JSON.stringify(_this.videoFile))   
},  
fai:function(){  
    console.log("chooseVideo fail ="+JSON.stringify(res))  

}  
})  
},  

uploadFile(_file){  

        console.log("uploadFiles _file ="+JSON.stringify(_file))  
    var _this = this;  
    var successCallback = function(res){  
            console.log('uploadFile success '+JSON.stringify(res))  
        };  
        var failCallback = function(error){  
            console.log('uploadFile fail error = '+JSON.stringify(error))  
        }  
    var param = {url:"http://192.168.11.71:8080/upload/",file:{},name:_file.fileName,filePath:_file.filePath,success:successCallback,fail:failCallback}  
    if(_file.file !== undefined){  
        param.file = _file.file  
    }  
    uni.uploadFile(param)  
}  
操作步骤:
1. 调用 uni.chooseVideo() 方法获取视频的路径
2. 将1中返回的视频的路径传入uni.uploadFile(),上传视频到服务器
预期结果:
成功上传
实际结果:
上传失败
I/console: [LOG]uploadFiles _file ={"filePath":"/storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/temp/compress_video_22234740.mp4","fileName":"compress_video_22234740"} at pages/common_function/upload.vue:145
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/www/storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/temp/compress_video_22234740.mp4: open
bug描述:
uni.chooseVideo() 在Android 端 返回的文件路径是物理的文件路径,导致uni.uploadFile() 上传文件失败

更多关于uni-app中uni.chooseVideo()在Android端返回的物理文件路径导致uni.uploadFile()上传文件失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

你用最新版本 3.1.19试试

更多关于uni-app中uni.chooseVideo()在Android端返回的物理文件路径导致uni.uploadFile()上传文件失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在文件物理地址前面加上file://,例如: file:///storage/emulated/0/Android/data/com.sky.libapp/apps/UNIB0EC99A/temp/compress_video_1824232.mp4 文档没有说明这样的操作,自己试出来的

这是一个典型的Android文件路径权限问题。uni.chooseVideo()在Android端返回的是绝对物理路径,而uni.uploadFile()在Android环境下默认会在路径前加上应用沙箱路径前缀,导致最终路径错误。

从错误日志可以看到:

  • 实际文件路径:/storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/temp/compress_video_22234740.mp4
  • 上传时拼接的路径:/storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/www/storage/emulated/0/Android/data/com.skyworth.libapp/apps/UNIB0EC99A/temp/compress_video_22234740.mp4

解决方案:

  1. 使用临时文件路径处理
// 在chooseVideo的success回调中直接使用res.tempFile对象
uploadFile(_file) {
    uni.uploadFile({
        url: "http://192.168.11.71:8080/upload/",
        file: _file.file, // 直接使用tempFile对象
        name: _file.fileName,
        filePath: _file.filePath,
        success: function(res) {
            console.log('uploadFile success '+JSON.stringify(res))
        },
        fail: function(error) {
            console.log('uploadFile fail error = '+JSON.stringify(error))
        }
    })
}
  1. 路径兼容处理
// 检测Android平台并处理路径
uploadFile(_file) {
    let filePath = _file.filePath;
    // 如果是Android且路径已经是绝对路径,直接使用
    if (uni.getSystemInfoSync().platform === 'android' && filePath.startsWith('/')) {
        // 直接使用绝对路径
    }
    
    uni.uploadFile({
        url: "http://192.168.11.71:8080/upload/",
        filePath: filePath,
        name: _file.fileName,
        success: function(res) {
            console.log('uploadFile success '+JSON.stringify(res))
        },
        fail: function(error) {
            console.log('uploadFile fail error = '+JSON.stringify(error))
        }
    })
}
回到顶部