📱

使用调试工具解决Android App生成File文件失败问题

 
如果不知道什么是 PCF组件,可以看我的《什么是微软PCF组件》文章
此App指的是微软的Field Service
 

出现问题的场景:

需要使用PCF做一个文件上传组件,并在Field Service中使用。PCF有获取文件的api,这个api返回的数据是base64格式的,但是需要把文件切分成小文件,再进行上传,最后上传的数据类型也要是base64。
  • 我使用的方案是将base64转为file文件,然后使用file.slice进行切分。
  • 在web中使用Field Service进行文件上传的时候,没有出现问题。
  • 在IOS中安装Field Service进行文件上传的时候,没有出现问题。
  • 在Android安装Field Service进行文件上传的时候,出现了问题,文件上传失败。

问题的排查:

  1. 由于是在手机App里面,排查哪一步出现了问题有点困难,因为已经打包上传到App里面使用了,那有什么办法可以调试呢
  1. 只有Android出现了这个问题,说明整体代码没有什么问题,可能是安卓文件处理方式的问题
 

问题的解决:

  1. 在网上找到了 Field Service如何在Android如何调试的方法
    1. 1.1 在Android设备上启用开发者选项和 USB 调试 配置设备上的开发者选项
      1.2 在 Microsoft Edge 或 Chrome 浏览器中,发现 Android 设备 Chrome 开发人员:远程调试 Android 设备
      • 在 Microsoft Edge 上输入:edge://inspect/#devices
      • 在 Chrome 上输入:chrome://inspect/#devices
      1.3 配置移动应用程序
      • 在移动应用程序中,转到 Power Apps 列表并选择菜单按钮
      • 确保启用模型驱动应用的远程调试开关已打开
notion image
  • 启用此选项时,会出现一个确认对话框。选择“确认”
notion image
1.4 从开发机器调试
  • 将您的计算机插入您的 Android 设备。
  • 从 Power Apps 或 Field Service Mobile 应用程序打开任何模型驱动应用。
  • 在浏览器页面的远程目标chrome://inspect/#devices 部分中找到您的组织 URL 。
notion image
 
  1. 一边操作一边看打印出来的数据,发现获取数据和将数据转为ArrayBuffer也没有问题,但是转为file文件却出现了问题。但是web是转为file是没有问题的,那么说明是文件系统的问题
  1. 既然转为ArrayBuffer没有问题,那么就直接切分ArrayBuffer,然后再将切分的ArrayBuffer实例转为base64,然后上传。最后的结果是成功了。
notion image
 

具体代码:

// 将 base64 转换为 ArrayBuffer const base64ToArrayBuffer = base64 => { const binaryString = atob(base64); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; }; // 将 ArrayBuffer 转换为 base64 const arrayBufferToBase64 = buffer => { const binary = Array.from(new Uint8Array(buffer)).map(byte => String.fromCharCode(byte)).join(''); return btoa(binary); }; // 将 base64 数据分割为指定大小的块 const splitBase64IntoChunks = (base64Data, chunkSize) => { const arrayBuffer = base64ToArrayBuffer(base64Data); const chunks = []; let offset = 0; while (offset < arrayBuffer.byteLength) { const chunk = arrayBuffer.slice(offset, offset + chunkSize); chunks.push(arrayBufferToBase64(chunk)); offset += chunkSize; } return chunks; }; // 示例 base64 数据 const base64Data = "your_base64_data_here"; const chunkSize = 5 * 1024 * 1024; // 5MB in bytes // 将 base64 数据分割为 5MB 块 const base64Chunks = splitBase64IntoChunks(base64Data, chunkSize); // 输出分割后的 base64 块 console.log(base64Chunks);