李钊
李钊
  • 发布:2020-08-20 10:47
  • 更新:2020-09-06 20:02
  • 阅读:1621

【报Bug】uniapp中android.util.Base64的Base64.decode(base64Str,0);解码后为null

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 2.8.6

手机系统: Android

手机系统版本号: Android 9.0

手机厂商: 华为

手机机型: 小米note3

页面类型: vue

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
/文件的写入操作传入要写入文件名,base64  
function lzFileWriter(base64,fileName) {  
    return new Promise((result,reject)=>{  
        // PRIVATE_WWW:本地文件系统常量,Number类型,固定值1。应用运行资源目录,仅本应用可访问。 为了确保应用资源的安全性,此目录只可读。  
        // PRIVATE_DOC 本地文件系统常量,Number类型,固定值2。应用私有文档目录,仅本应用可读写。  
        plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {  
            /*  
            fs.root是根目录操作对象DirectoryEntry  
            getFile(path,flag,succesCB,errorCB)创建或打开文件  
                path: ( DOMString ) 必选 要操作文件相对于当前目录的地址  
                flag: ( Flags ) 可选 要操作文件或目录的参数 create: (Boolean 类型 )是否创建对象标记 指示如果文件或目录不存在时是否进行创建,默认值为false  
                succesCB: ( EntrySuccessCallback ) 可选 创建或打开文件成功的回调函数  
                errorCB: ( FileErrorCallback ) 可选 创建或打开文件失败的回调函数  
            */   
           // 创建或打开文件  
            fs.root.getFile(fileName,{create:true},function(fileEntry) {  
                // 获得平台绝对路径  
                var fullPath = fileEntry.fullPath;    
                console.log('平台绝对路径',fullPath);  
                // 引入安卓原生类  
                var Base64 = plus.android.importClass("android.util.Base64");  
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");  
                //如果文件不存在则创建文件,如果文件存在则删除文件后重新创建文件  
                var out = new FileOutputStream(fullPath);   
                /**  
                 * 此处需要把base64前缀去除,解码后,在写入字节流数组  
                 * 去除头部如data:image/jpg;base64,留下base64编码后的字符串  
                **/  
                let index=base64.indexOf(',')  
                let base64Str=base64.slice(index+1,base64.length)  
                console.log(base64Str.length);  
                //base64解密得到字节流bytes;  
                var bytes = Base64.decode(base64Str,0);  

                let string=quantum.Base64Decode(base64Str)  
                var bytes = plus.android.invoke(string,'getBytes','utf8');  
                try{  
                    console.log(bytes);  
                    out.write(bytes); // byte 数组写入此文件输出流中。  
                    out.flush(); //刷新写入文件中去。  
                    out.close(); //关闭此文件输出流并释放与此流有关的所有系统资源。  
                    result(fullPath)  
                }catch(e){    
                    console.log(e.message);    
                    reject(e.message)  
                }  
                // 下面的方法只能写入字符串,无法写入字节流bytes  
                // fileEntry文件系统中的文件对象,用于管理特定的本地文件  
                // fileEntry.file(function(file) {  
                //  /*createWriter获取文件关联的写文件操作对象FileWriter  
                //      abort: 终止文件写入操作  
                //      seek: 定位文件操作位置  
                //      truncate: 按照指定长度截断文件  
                //      write: 向文件中写入数据  
                //  */  
                //  fileEntry.createWriter(function(FileWriter) {  
                //      FileWriter.write(base64);  
                //      FileWriter.onwriteend=function(res){  
                //          console.log(res.target.fileName);  
                //          result(res.target.fileName)  
                //      }  
                //      FileWriter.onerror=function(error){  
                //          console.log(error);  
                //          reject(error)  
                //      }  
                //  }, function(e) {  
                //      console.log(e);  
                //  });  
                // });  
            });  
        });  
    })  
}

操作步骤:

引入安卓原生类 var Base64 = plus.android.importClass("android.util.Base64");
//base64解密得到字节流bytes;
var bytes = Base64.decode(base64Str,0);
发现超过800kb文件解码后null,但是小的文件解码是可以的

预期结果:

5m文件以内都可解码

实际结果:

解码为null

bug描述:

引入安卓原生类 var Base64 = plus.android.importClass("android.util.Base64");
//base64解密得到字节流bytes;
var bytes = Base64.decode(base64Str,0);
发现解码后null,但是小的文件解码是可以的

2020-08-20 10:47 负责人:DCloud_Android_ST 分享
已邀请:
DCloud_Android_ST

DCloud_Android_ST

NJS对传输字节流有限制不得超过10KB。具体与手机系统版本有关

李钊

李钊 (作者) - 李钊

已经解决了大小限制问题,写了个原生插件Helper我的博客地址https://www.cnblogs.com/lizhao123/p/13528046.html有详细讲解

//文件的写入操作传入要写入文件名,base64  
function lzFileWriter(base64,fileName) {  
    return new Promise((result,reject)=>{  
        // PRIVATE_WWW:本地文件系统常量,Number类型,固定值1。应用运行资源目录,仅本应用可访问。 为了确保应用资源的安全性,此目录只可读。  
        // PRIVATE_DOC 本地文件系统常量,Number类型,固定值2。应用私有文档目录,仅本应用可读写。  
        plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {  
            /*  
            fs.root是根目录操作对象DirectoryEntry  
            getFile(path,flag,succesCB,errorCB)创建或打开文件  
                path: ( DOMString ) 必选 要操作文件相对于当前目录的地址  
                flag: ( Flags ) 可选 要操作文件或目录的参数 create: (Boolean 类型 )是否创建对象标记 指示如果文件或目录不存在时是否进行创建,默认值为false  
                succesCB: ( EntrySuccessCallback ) 可选 创建或打开文件成功的回调函数  
                errorCB: ( FileErrorCallback ) 可选 创建或打开文件失败的回调函数  
            */   
           // 创建或打开文件  
            fs.root.getFile(fileName,{create:true},function(fileEntry) {  
                // 获得平台绝对路径  
                var fullPath = fileEntry.fullPath;    
                console.log('平台绝对路径',fullPath);  
                // 引入安卓原生类  
                // var Base64 = plus.android.importClass("android.util.Base64");  
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");  
                //如果文件不存在则创建文件,如果文件存在则删除文件后重新创建文件  
                var out = new FileOutputStream(fullPath);   
                /**  
                 * 此处需要把base64前缀去除,解码后,在写入字节流数组  
                 * 去除头部如data:image/jpg;base64,留下base64编码后的字符串  
                **/  
                let index=base64.indexOf(',')  
                let base64Str=base64.slice(index 1,base64.length)  
                //base64编码的字符串获取bytes字节流,此bytes为编码的  
                let bytes = Helper.Str2Bytes(base64Str,'utf-8').data;  
                /**  
                 * bytes再去解密,得到原始的字节流bytes  
                 * 由于使用njs的android.util.Base64的var bytes = Base64.decode(base64Str,0);解码有大小限制,只能写原始插件Helper  
                **/  
                bytes=Helper.Base64Decode(bytes,0).data;  
                /**  
                 * base64解密得到字节流bytes;但是njs有大小限制,解码不能超过100kb具体与手机系统版本有关  
                 * Base64.decode(base64Str,0);此方法相当于上面的操作  
                 * 【let bytes = Helper.Str2Bytes(base64Str,'utf-8').data;   bytes=Helper.Base64Decode(bytes,0).data;】  
                **/  
                // var bytes = Base64.decode(base64Str,0);//有大小限制已舍弃此方法  
                try{  
                    out.write(bytes); // byte 数组写入此文件输出流中。  
                    out.flush(); //刷新写入文件中去。  
                    out.close(); //关闭此文件输出流并释放与此流有关的所有系统资源。  
                    result(fullPath)  
                }catch(e){    
                    console.log(e.message);    
                    reject(e.message)  
                }  
                // 下面的方法只能写入字符串,无法写入字节流bytes  
                // fileEntry文件系统中的文件对象,用于管理特定的本地文件  
                // fileEntry.file(function(file) {  
                //  /*createWriter获取文件关联的写文件操作对象FileWriter  
                //      abort: 终止文件写入操作  
                //      seek: 定位文件操作位置  
                //      truncate: 按照指定长度截断文件  
                //      write: 向文件中写入数据  
                //  */  
                //  fileEntry.createWriter(function(FileWriter) {  
                //      FileWriter.write(base64);  
                //      FileWriter.onwriteend=function(res){  
                //          console.log(res.target.fileName);  
                //          result(res.target.fileName)  
                //      }  
                //      FileWriter.onerror=function(error){  
                //          console.log(error);  
                //          reject(error)  
                //      }  
                //  }, function(e) {  
                //      console.log(e);  
                //  });  
                // });  
            });  
        });  
    })  
}
8***@qq.com

8***@qq.com

楼主,qq加你未回复,问下大伙怎么解决的。
未想到安卓写入个文件这么多障碍,只能写文本的话根本无法实现很多东西。

  • 李钊 (作者)

    好的我同意下

    2020-09-07 17:54

  • 1***@qq.com

    回复 李钊: 加你了,麻烦同意下

    2020-12-20 15:30

该问题目前已经被锁定, 无法添加新回复