Ionic Capacitor cordova plugin unable to write image to library on Android

回眸只為那壹抹淺笑 提交于 2020-12-15 05:35:32

问题


I am trying to use cordova-plugin-document-scanner with Ionic Capacitor for Android, but after the image is captured and when image crop UI should be displayed, it just returns to the capture screen again. This is the issue on the github repo. This is what seems relevant in the logcat console:

2020-08-03 13:26:05.320 27707-27707/si.test.app D/ViewRootImpl@9f2e8cd[ScanActivity]: Relayout returned: old=(0,0,1080,2280) new=(0,0,1080,2280) req=(1080,2280)4 dur=8 res=0x1 s={false 0} ch=false 2020-08-03 13:26:05.321 27707-27707/si.test.app D/ViewRootImpl@9f2e8cd[ScanActivity]: stopped(false) old=true 2020-08-03 13:26:05.328 27707-27707/si.test.app W/System.err: java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)

2020-08-03 13:42:50.749 1278-1278/? E/Util: writeImageDataToRequestedUri : failed to make directory or the directory already existed.

2020-08-03 13:42:50.760 1278-1278/? E/Util: writeImageDataToRequestedUri : Returned because outputStream IOException.

This is my configuration:

  • Device: Samsung Galaxy S10e
  • OS: Android 10
  • @capacitor/core : 2.3.0
  • @capacitor/android: 2.3.0
  • cordova-plugin-document-scanner: 4.2.5

Is it possible, that Cordova and Capacitor have different paths to files on the device? Where could I fix that? Any help greatly appriciated :)


回答1:


I implemented this in my project using Ionic 5 and Capacitor. It is long code. Try this and maybe help you.

Install this npms

npm install cordova-plugin-crop
npm install @ionic-native/crop

npm install cordova-plugin-ionic-webview
npm install @ionic-native/ionic-webview

Then create service file. ex: photo.service

Then add below code according to your case. I added my full code to here because it include all things.

There are two method.

getImageCam() - get image from camera > source: CameraSource.Camera

getImageGall() - get image from gallery > source: CameraSource.Photos

import { Injectable } from "@angular/core";
import {
  Plugins,
  CameraResultType,
  CameraPhoto,
  CameraSource,
} from "@capacitor/core";
import { Crop } from "@ionic-native/crop/ngx";
import { WebView } from "@ionic-native/ionic-webview/ngx";
//import { File } from "@ionic-native/file/ngx";

const { Camera, Filesystem, Storage } = Plugins;

@Injectable({
  providedIn: "root",
})
export class PhotoService {
  newCapturedImg: any = null;
  ImgNameStart: any = "yourName";
  formDataImage: any;
  cropImage: CameraPhoto;

  constructor(private crop: Crop, private webview: WebView) {}

  public async getImageCam() {
    // Take a photo
    const capturedPhoto = await Camera.getPhoto({
      resultType: CameraResultType.Uri,
      source: CameraSource.Camera,
      quality: 100,
      // allowEditing: true,
      // height: 300,
      // width: 300
    });

    console.log(capturedPhoto);

    this.crop
      .crop(capturedPhoto.path, {
        quality: 100,
      })
      .then(
        (newImage) => {
          this.newCapturedImg = this.webview.convertFileSrc(newImage);

          //console.log("new image path is: " + newImage);
          //console.log("new image webpath is: " + this.newCapturedImg);

          this.cropImage = {
            path: newImage,
            webPath: this.newCapturedImg,
            format: "jpeg",
          };

          const savedImageFile =  this.savePicture(this.cropImage);
        },
        (error) => console.error("Error cropping image", error)
      );
  }

  public async getImageGall() {
    // Take a photo
    const capturedPhoto = await Camera.getPhoto({
      resultType: CameraResultType.Uri,
      source: CameraSource.Photos,
      quality: 100,
      // allowEditing: true,
      // height: 300,
      // width: 300,
    });

    this.crop
      .crop(capturedPhoto.path, {
        quality: 100,
      })
      .then(
        (newImage) => {
          this.newCapturedImg = this.webview.convertFileSrc(newImage);

          //console.log("new image path is: " + newImage);
          //console.log(this.newCapturedImg);

          this.cropImage = {
            path: newImage,
            webPath: this.newCapturedImg,
            format: "jpeg",
          };

          const savedImageFile = this.savePicture(this.cropImage);
        },
        (error) => console.error("Error cropping image", error)
      );

  }    


  private async savePicture(cameraPhoto: CameraPhoto) {
    const blobData = await this.readABlob(cameraPhoto);
    this.formDataImage = blobData;
  }

  private async readABlob(cameraPhoto: CameraPhoto) {
    const response = await fetch(cameraPhoto.webPath!);
    const blob = await response.blob();
    console.log("blob --> ", blob);
    return blob;
  }


  createFileName() {
    let d = new Date();
    let n = d.getTime();
    let newFileName = `${this.ImgNameStart + n}.jpg`;
    return newFileName;
  }
}

interface Photo {
  filepath: string;
  webviewPath: string;
  base64?: string;
}

You can access service variable like this from any component.

example.page.ts

import { PhotoService } from "../../services/photo.service";

...

  constructor(public photoService: PhotoService) {}

...

yourMethod() {
  this.photoService.getImageCam() // or getImageGall()


  let formDataImage = this.photoService.formDataImage;
  let imageName = this.photoService.createFileName();
  let urlToImageSrc = this.photoService.newCapturedImg;
}


来源:https://stackoverflow.com/questions/63241127/ionic-capacitor-cordova-plugin-unable-to-write-image-to-library-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!