typescript - 如何在Ionic4 Angular中使用电容器保存下载的文件?

标签 typescript ionic-framework ionic4 capacitor

我最近以网络应用程序和 native Android应用程序的形式发布了Ionic 4 Angular App。
在 native Android应用程序中,除了保存下载的文件外,其他所有功能都可以正常运行。

要下载和保存文件,我总是使用file-saver npm软件包,如下所示(这是我每次必须下载某些内容(从PDF到图像等)时都会调用的共享服务):

import { saveAs } from 'file-saver';

// ...

saveGenericFile(api: string, fileinfos: any, idFile: string): any {
    let mediaType = 'application/pdf';
    let fileName = '';

    if (fileinfos != null) {
      mediaType = fileinfos.contentType;
      fileName = fileinfos.fileName;
    }

    const headers = this.base.commonHeader;
    const url = this.baseUrl + api + '?id=' + idFile;
    this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
      (response) => {
        // tslint:disable-next-line: prefer-const
        let blob = new Blob([response], { type: mediaType });
        saveAs(blob, fileName);
      }, e => {
        console.error(e);
        this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
      }, () => {
        /* do nothing */
      }
    );
  }

就像我在上面说的那样,这个代码片段可以正常工作,但是只是在我必须从Web发布中保存某些内容时。

我唯一能找到的在线示例都是有关Cordova和/或以前/过时的版本的信息。
关于电容器,我刚刚找到了this documentation,并从中找到了以下代码片段:
import { Plugins, FilesystemDirectory, FilesystemEncoding } from '@capacitor/core';

const { Filesystem } = Plugins;

fileWrite() {
  try {
    Filesystem.writeFile({
      path: 'secrets/text.txt',
      data: "This is a test",
      directory: FilesystemDirectory.Documents,
      encoding: FilesystemEncoding.UTF8
    });
  } catch(e) {
    console.error('Unable to write file', e);
  }
}

但是问题是我上面的函数返回一个blob,而这个blob只接受一个数据字符串。

因此,是否有任何电容器 native 等效功能,我既可以在以Web应用程序运行时又可以在以Android native 应用程序运行时用于下载(并保存)Blob文件?

更新

我也尝试了以下方法,但是不起作用:
saveGenericFile(api: string, fileinfos: any, gidFile: string): any {
    let mediaType = 'application/pdf';
    let fileName = '';

    if (fileinfos != null) {
      mediaType = fileinfos.contentType;
      fileName = fileinfos.fileName;
    }

    const headers = this.base.commonHeader;
    const url = this.baseUrl + api + '?id=' + gidFile;
    this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
      (response) => {
        if (!this.useCordovaDl) {
          // tslint:disable-next-line: prefer-const
          let blob = new Blob([response], { type: mediaType });
          saveAs(blob, fileName);
        } else {
          this.blobFileWrite(fileName, response);
        }
      }, e => {
        console.error(e);
        this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
      }, () => {
        /* do nothing */
      }
    );
  }

  blobFileWrite(filename: string, blobfile: Blob) {
    const reader = new FileReader();

    // This fires after the blob has been read/loaded.
    reader.addEventListener('loadend', (e: any) => {
      const text = e.srcElement.result;
      this.fileWrite(filename, text);
    });

    // Start reading the blob as text.
    reader.readAsText(blobfile);
  }

  fileWrite(filename: string, filedata: string) {
    try {
      Filesystem.writeFile({
        path: filename,
        data: filedata
        // ,
        // directory: FilesystemDirectory.Documents,
        // encoding: FilesystemEncoding.UTF8
      });
    } catch (e) {
      console.error('Unable to write file', e);
    }
  }

更新#2

看起来与there's still an opened issue on GitHub有关使用Capacitor保存Blob数据有关。同时,我将寻找Cordova解决方案。或者,如果平台是android或ios,我将仅禁用每个下载按钮。
如果可以的话,我将在此处发布所有可行的Cordova解决方法

最佳答案

如果要实现的目标是将文件保存在文件系统中,则可以使用字符串base64将其保存到文件系统中

image = "data:image/png;base64,iVBORw0KGgo... bla bla bla"
Capacitor.Plugins.Filesystem.appendFile({
    data:image,
    path:"directory/image.png",
    directory:"DOCUMENTS"
}).then(c=>{console.log("se escribiooo")})

其结果在文件系统中的图像中(我只是在android仿真器中尝试过此代码),只需使用方法appendFile代替writeFile,并使用base64代替blob,如果只有blob,则只需将其转换为base64

关于typescript - 如何在Ionic4 Angular中使用电容器保存下载的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56644178/

相关文章:

angular - 将 ionic 选择选项传递给函数 - Ionic 4

angular - "const {next, error} = observer"语法是什么?

javascript - ionic.bundle.js :25642 Error: [$injector:unpr] Unknown provider: $cordovaGeolocationProvider <- $cordovaGeolocation <- AgeCtrl

angular - Cordova AppCenter 插件 : Query fired: did not receive both families in time for in. appcenter.ms:443

android - HTML5 Canvas元素不会出现在已编译的Android Ionic中,但可以在浏览器“Ionic Serve”中使用

python - 如何在 django Rest 中启用基于函数的 View 的 cors origin?

javascript - 收到 fcm 推送通知后更新页面上的 View 并且我在同一页面上

javascript - 在 props 接口(interface)中访问 React 类型

javascript - Angular 5(onClick)事件触发两次

javascript - MUI v5 主题与情感/mui