Ionic 3 将 URL 读取为 Android 中的 base64

Ionic 3 Read URL as base64 in Android

我正在使用 Ionic 3 相机和文件插件来处理来自用户 Android 图库应用的图像选择。插件 returns 一个文件 uri,我想用它来使用文件插件提取 base64 编码的图像,但是当我尝试从缓存目录中读取文件时,我得到一个 NOT_FOUND_ERR。这是我的代码示例和一些日志输出:

this.camera.getPicture(this.getCameraOptionsForPhotoLibrary()).then((fileUri: string) => {

  const fileNameIndex: number = fileUri.lastIndexOf('/') + 1;

  // file:///storage/emulated/0/Android/data/com.myDomain.myApp/cache/
  const cacheDirectoryFromFileUri = fileUri.substring(0, fileNameIndex );

  //  FB_IMG_1532921240445.jpg?1532982282636 
  const fileName = fileUri.substring(fileNameIndex);

  this.file.readAsDataURL(cacheDirectoryFromFileUri, fileName).then(base64 => {
    alert('base64 cacheDirectoryFromFileUri success: ' + JSON.stringify(base64));
  }, err => {
    alert('base64 cacheDirectoryFromFileUri err: ' + JSON.stringify(err));
  });

请告诉我,我可以提供更多信息来帮助解决问题。

在尝试重现您的错误时,我没有得到 NOT_FOUND_ERR。

虽然,这个代码块

this.camera.getPicture(this.getCameraOptionsForPhotoLibrary()).then((fileUri: string) => {

  const fileNameIndex: number = fileUri.lastIndexOf('/') + 1;

  // file:///storage/emulated/0/Android/data/com.myDomain.myApp/cache/
  const cacheDirectoryFromFileUri = fileUri.substring(0, fileNameIndex );

  //  FB_IMG_1532921240445.jpg?1532982282636 
  const fileName = fileUri.substring(fileNameIndex);

  this.file.readAsDataURL(cacheDirectoryFromFileUri, fileName).then(base64 => {
    alert('base64 cacheDirectoryFromFileUri success: ' + JSON.stringify(base64));
  }, err => {
    alert('base64 cacheDirectoryFromFileUri err: ' + JSON.stringify(err));
  });
}

给我这个错误

base64 cacheDirectoryFromFileUri err: {"code":5,"message":"ENCODING_ERR"}

我正在使用这些选项

{
  quality: 100,
  destinationType: this.camera.DestinationType.FILE_URI,
  encodingType: this.camera.EncodingType.JPEG,
  mediaType: this.camera.MediaType.ALLMEDIA,
  sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
}

下面一行

const cacheDirectoryFromFileUri = fileUri.substring(0, fileNameIndex );

给我这样的东西

/storage/emulated/0/WhatsApp/Media/WhatsApp Images/

将该行更改为以下内容后

const cacheDirectoryFromFileUri = 'file://'+fileUri.substring(0, fileNameIndex );

问题已解决。

或者,如果您在从相机拍摄图像后尝试从缓存中获取图像并希望获取 base64 编码的字符串,则可以使用 Camera.DestinationTypeDATA_URL

destinationType: this.camera.DestinationType.DATA_URL

我无法按照描述的方式复制 Patra 的回答,但自从我第一次发布以来,我确实设法通过测试提取了一些有用的信息。

在某些情况下,我发现如果删除 ? (FB_IMG_1532921240445.jpg?1532982282636),结果成功returned。但这是以几个 device/configuration 场景为条件的。例如,如果我发布 APK,它会在 Pixel 2 上的 Oreo 上失败。事实上,它在没有调用错误回调的情况下失败了,所以我什至无法处理失败。但出于某种原因,如果我在同一设备上使用 -lc 标志从 CLI 构建,它将按预期 return base64 结果。

在测试 7.0 和 7.1 模拟设备时,无论构建配置如何,它都能按预期工作。

令人沮丧的是,设备和配置之间的行为明显不同。我对 livereload 的差异特别好奇,如果有人对为什么文件插件行为会根据此标志发生变化有任何见解,那将是很高兴知道的。

我仍在努力解决这个问题,尽管除了破解插件之外我不知道该去哪里。我已经尝试过 Base64 Native Plugin,它最初似乎可以工作,但它似乎没有得到积极管理,并且根据 github 页面有很多未解决的问题。我可能最终会结合使用 File 和 Base64 插件来获得我现在需要的东西。

/** 更新 **/

我们团队的一名成员在这里找到了我们问题的具体答案: https://forum.ionicframework.com/t/file-readastext-never-resolves/85375/24

如果此 link 出现故障,我们将采取以下措施修复它:

在index.html

中的polyfills.js之后放置cordova.js

多么可怕的错误。