uni-app为什么在安卓调用uni.uploadFile时,基座运行没问题,打包成apk就出错

uni-app为什么在安卓调用uni.uploadFile时,基座运行没问题,打包成apk就出错

代码示例

模板部分

<template>  
    <view class="content">  
        <button @click="uploadFiles">点击上传</button>  
        <view>上传前的tempFiles:</view>  
        <view class="w-[400px] h-[400px] overflow-scroll">{{ tempFiles }}</view>  
        <view>-----------------</view>  
        <view>上传得到的数据src:</view>  
        <view class="w-[400px] h-[400px] overflow-scroll">{{ src }}</view>  
    </view>  
</template>  

脚本部分

<script>  
import { getAccessToken } from '@/utils/auth'  
import common from '@/utils/common.js'  

export default {  
    data() {  
        return {  
            src: '',  
            tempFiles: ''  
        }  
    },  
    methods: {  
        //h5、微信小程序、app上传文件  
        uploadFiles() {  
            //#ifdef H5  
            uni.chooseFile({  
                count: 1,  
                success: res => {  
                    uni.uploadFile({  
                        url: 'https://我的服务器/sass/api/admin-api/infra/file/upload',  
                        file: res.tempFiles[0],  
                        name: 'file',  
                        header: {  
                            Authorization: getAccessToken() ? 'Bearer ' + getAccessToken() : ''  
                        },  
                        success: (res) => {  
                            this.src = JSON.parse(res.data)?.data  
                            console.log('res', JSON.parse(res.data)?.data)  
                        },  
                        fail: (err) => {  
                            console.log('err', err)  
                        }  
                    });  
                }  
            });  
            //#endif  
            // #ifdef MP-WEIXIN  
            uni.chooseMessageFile({  
                count: 1,  
                success: res => {  
                    uni.uploadFile({  
                        url: 'https://我的服务器/sass/api/admin-api/infra/file/upload',  
                        filePath: res.tempFiles[0].path,  
                        name: 'file',  
                        header: {  
                            Authorization: getAccessToken() ? 'Bearer ' + getAccessToken() : ''  
                        },  
                        success: (res) => {  
                            this.src = JSON.parse(res.data)?.data  
                            console.log('res', JSON.parse(res.data)?.data)  
                        },  
                        fail: (err) => {  
                            console.log('err', err)  
                        }  
                    });  
                }  
            });  
            //#endif  
            // #ifdef APP-VUE  
            common.androidChooseFile(res => {  
                var tempFiles = res;  
                this.tempFiles = tempFiles  
                uni.uploadFile({  
                    url: 'https://我的服务器/sass/api/admin-api/infra/file/upload',  
                    filePath: tempFiles,  
                    name: 'file',  
                    header: {  
                        Authorization: getAccessToken() ? 'Bearer ' + getAccessToken() : '',  
                        'content-type': 'application/x-www-form-urlencoded; charset=UTF-8'  
                    },  
                    success: (res) => {  
                        console.log('安卓app的res', JSON.parse(res.data)?.data)  
                        this.src = res  
                    },  
                    fail: (err) => {  
                        console.log('安卓app的err', err)  
                    }  
                });  
            }, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')  
            // #endif  
        },  
    },  
}  
</script>  

工具函数

var common = {}  

common.androidChooseFile = (callback, acceptType) => {  
    var CODE_REQUEST = 1000;  
    var main = plus.android.runtimeMainActivity();  
    if (plus.os.name == 'Android') {  
        var Intent = plus.android.importClass('android.content.Intent');  
        var intent = new Intent(Intent.ACTION_GET_CONTENT);  
        intent.addCategory(Intent.CATEGORY_OPENABLE);  
        intent.setType("*/*");  
        main.onActivityResult = (requestCode, resultCode, data) => {  
            if (requestCode == CODE_REQUEST) {  
                const uri = data.getData();  
                plus.android.importClass(uri);  
                const Build = plus.android.importClass('android.os.Build');  
                const isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;  
                const DocumentsContract = plus.android.importClass('android.provider.DocumentsContract');  
                if (isKitKat && DocumentsContract.isDocumentUri(main, uri)) {  
                    if ("com.android.externalstorage.documents" == uri.getAuthority()) {  
                        var docId = DocumentsContract.getDocumentId(uri);  
                        var split = docId.split(":");  
                        var type = split[0];  
                        if ("primary" == type) {  
                            var Environment = plus.android.importClass('android.os.Environment');  
                            callback(Environment.getExternalStorageDirectory() + "/" + split[1]);  
                        } else {  
                            var System = plus.android.importClass('java.lang.System');  
                            var sdPath = System.getenv("SECONDARY_STORAGE");  
                            if (sdPath) {  
                                callback(sdPath + "/" + split[1]);  
                            }  
                        }  
                    } else if ("com.android.providers.downloads.documents" == uri.getAuthority()) {  
                        var id = DocumentsContract.getDocumentId(uri);  
                        var ContentUris = plus.android.importClass('android.content.ContentUris');  
                        var contentUri = ContentUris.withAppendedId(  
                            Uri.parse("content://downloads/public_downloads"), id);  
                        callback(getDataColumn(main, contentUri, null, null));  
                    } else if ("com.android.providers.media.documents" == uri.getAuthority()) {  
                        var docId = DocumentsContract.getDocumentId(uri);  
                        var split = docId.split(":");  
                        var type = split[0];  
                        var MediaStore = plus.android.importClass('android.provider.MediaStore');  
                        if ("image" == type) {  
                            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
                        } else if ("video" == type) {  
                            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
                        } else if ("audio" == type) {  
                            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  
                        } else {  
                            contentUri = MediaStore.Files.getContentUri("external");  
                        }  
                        callback(getDataColumn(main, contentUri, selection, selectionArgs));  
                    }  
                } else if ("content" == uri.getScheme()) {  
                    callback(getDataColumn(main, uri, null, null));  
                } else if ("file" == uri.getScheme()) {  
                    callback(uri.getPath());  
                }  
            }  
        }  
        main.startActivityForResult(intent, CODE_REQUEST);  
    }  

    function getDataColumn(main, uri, selection, selectionArgs) {  
        plus.android.importClass(main.getContentResolver());  
        let cursor = main.getContentResolver().query(uri, ['_data'], selection, selectionArgs, null);  
        plus.android.importClass(cursor);  
        if (cursor != null && cursor.moveToFirst()) {  
            var column_index = cursor.getColumnIndexOrThrow('_data');  
            var result = cursor.getString(column_index)  
            cursor.close();  
            return result;  
        }  
        return null;  
    }  
}  
export default common

更多关于uni-app为什么在安卓调用uni.uploadFile时,基座运行没问题,打包成apk就出错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

云端打包后是什么现象?调用上传API有返回什么错误信息吗?

更多关于uni-app为什么在安卓调用uni.uploadFile时,基座运行没问题,打包成apk就出错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


可以打自定义基座包调试

在使用 uni-app 开发应用时,uni.uploadFile 在基座(HBuilderX 内置的调试环境)中运行正常,但打包成 APK 后出现问题,可能是由于以下几个原因:


1. 网络权限未正确配置

  • 原因:打包 APK 后,应用需要明确的网络权限才能访问网络。
  • 解决方法: 在 manifest.json 文件中,确保已经配置了网络权限:
    {
      "app-plus": {
        "distribute": {
          "android": {
            "permissions": [
              "<uses-permission android:name=\"android.permission.INTERNET\" />"
            ]
          }
        }
      }
    }
    

2. 服务器地址问题

  • 原因:在基座中运行时,可能会使用本地调试地址(如 localhost127.0.0.1),但打包成 APK 后,这些地址可能无法访问。
  • 解决方法: 确保 uni.uploadFileurl 参数是公网可访问的地址,而不是本地地址。

3. SSL/TLS 证书问题

  • 原因:如果服务器使用 HTTPS,但证书不被 Android 信任(如自签名证书),可能会导致请求失败。
  • 解决方法
    • 使用受信任的 SSL/TLS 证书。
    • 如果是测试环境,可以在 manifest.json 中允许忽略证书错误(不推荐用于生产环境):
      {
        "app-plus": {
          "ssl": {
            "verify": false
          }
        }
      }
      

4. 文件路径问题

  • 原因:在基座中使用的文件路径可能与打包后的 APK 文件路径不一致。
  • 解决方法: 确保文件路径是绝对路径,或者使用 uni.getFileSystemManager() 获取正确的文件路径。

5. Android 系统版本兼容性问题

  • 原因:某些 Android 系统版本对文件上传的处理方式可能不同。
  • 解决方法: 测试不同 Android 版本的兼容性,确保代码逻辑在多个版本上都能正常运行。

6. 打包配置问题

  • 原因:打包时可能遗漏了某些配置或资源。
  • 解决方法
    • 确保打包时选择了正确的配置。
    • 重新编译并打包 APK,检查是否有错误提示。
    • 使用 HBuilderX 的“发行”功能重新打包,而不是直接运行。

7. 调试和日志

  • 原因:基座中可能没有暴露某些错误,但在 APK 中会触发。
  • 解决方法
    • uni.uploadFilefail 回调中添加日志,查看具体的错误信息:
      uni.uploadFile({
        url: 'https://example.com/upload',
        filePath: 'filePath',
        name: 'file',
        success: (res) => {
          console.log('上传成功', res);
        },
        fail: (err) => {
          console.error('上传失败', err);
        }
      });
回到顶部