Cannot read a file using cordova file plugin in an

2019-02-20 19:04发布

I'm trying to use the Cordova file plugin to read an image saved in a mobile device so I can then get the base64 encoding of it, which I need to store remotely. The problem is that the resolveLocalFilesystemUrl() method, which is supposed to provide a File Entry object, instead seems to be returning an Entry object, which means I can't call file on it.

Here is the code that should be getting the File Entry object so I can use the file method to read the file itself.

MediaCapture.captureImage().then((images)=>{
  self.image = images[0].localURL;
  File.resolveLocalFilesystemUrl(self.image).then((entry)=>{
    entry.file(function (file) {
      var reader = new FileReader();

      reader.onloadend = function (encodedFile) {
        var src = encodedFile.target.result;
        src = src.split("base64,");
        var contentAsBase64EncodedString = src[1];
      };
      reader.readAsDataURL(file);
    })
  }).catch((error)=>{
    console.log(error);
  })
})

I am getting the following Typescript error, which tells me resolveLocalFilesystemUrl() is resolving with an Entry object, which doesn't have a file method. (The plugin documentation says resolveLocalFilesystemUrl resolves with a File Entry object, and such an object definitely has a file method which provides the file itself):

Property 'file' does not exist on type 'Entry'. 

I have experimented with the type of path I am providing resolveLocalFilesystemUrl(). I have tried full paths along the lines of /var/mobile/Applications//Documents/path/to/file and local URLs along the lines of cdvfile://localhost/temporary/filename - neither works

So the specific quesiton is why won't resolveLocalFilesystemUrl() provide me a File Entry object, or how I get it to do so? More generally, how can I read a file in Ionic 2 so that I can get a base64 version of it, if the above approach won't work.

Thank you!

3条回答
神经病院院长
2楼-- · 2019-02-20 19:23

I discovered that this problem was related to Typescript. resolveLocalFilesystemUrl() was actually resolving with a File Entry object (when I passed it a local url as the file path), but Typescript thought it was an Entry object and didn't think file() could be called on it.

The below fixed the issue by telling Typescript that entry object could be of any type, so could have any function or property called on it.

MediaCapture.captureImage().then((images)=>{
  self.image = images[0].localURL;
  File.resolveLocalFilesystemUrl(self.image).then((entry: any)=>{
    entry.file(function (file) {
      var reader = new FileReader();

      reader.onloadend = function (encodedFile: any) {
        var src = encodedFile.target.result;
        src = src.split("base64,");
        var contentAsBase64EncodedString = src[1];
      };
      reader.readAsDataURL(file);
    })
  }).catch((error)=>{
    console.log(error);
  })
})

Note that I also had to use encodedFile: any in order to allow target.result to be called on encodedFile

查看更多
冷血范
3楼-- · 2019-02-20 19:23

That is because resolveLocalFilesystemUrl is window object's function and not file.

MediaCapture.captureImage().then((images)=>{
  self.image = images[0].localURL;
  window.resolveLocalFilesystemUrl(self.image).then((entry)=>{
    entry.file(function (file) {
      var reader = new FileReader();

      reader.onloadend = function (encodedFile) {
        var src = encodedFile.target.result;
        src = src.split("base64,");
        var contentAsBase64EncodedString = src[1];
      };
      reader.readAsDataURL(file);
    })
  }).catch((error)=>{
    console.log(error);
  })
})

Or you could use ionic native version of the same plugin here

查看更多
淡お忘
4楼-- · 2019-02-20 19:34

I had a similar Problem in Ionic3 with @ionic-native/camera, the error was being given by destinationType: this.camera.DestinationType.FILE_URI and I solved it changing it to destinationType: this.camera.DestinationType.DATA_URL. This is how my Project looks like:

import { Camera, CameraOptions } from '@ionic-native/camera';
import { Image } from '****';

export class CameraService {
  public readonly cameraOptions: CameraOptions = {
    sourceType: this.camera.PictureSourceType.CAMERA,
    destinationType: this.camera.DestinationType.DATA_URL,
    encodingType: this.camera.EncodingType.JPEG,
    mediaType: this.camera.MediaType.PICTURE,
    correctOrientation: true
  };

  constructor(public camera: Camera) { }

  public takePicture(): Observable<Image> {
    return Observable.fromPromise(this.camera.getPicture(this.pictureOptions)).map(imageSrc => {
      this.base64Image = 'data:image/jpeg;base64,' + imageSrc;
      return new Image('CameraPhoto.jpeg', this.base64Image);
    });
  }
}

Class Image looks like

export class Image {
  public readonly name: string;
  public readonly fileURI: string;
  public readonly file?: File;

  constructor(name: string, fileURI: string, file?: File) {
    this.name = name;
    this.fileURI = fileURI;
    this.file = file;
  }
}

I hope it could help someone. Cheers!

查看更多
登录 后发表回答