I have a problem where the uri returned is in the format:
"content://com.android.providers.media.documents/document/image%3A18112"
instead of:
"/storage/emulated/0/WhatsApp/Media/WhatsApp Animated Gifs/VID-20191026-WA0003.mp4"
This seems to only be a problem when selecting a picture from the gallery. With video files it is the correct format. my version for the plugin is:
"@ionic-native/camera": "^5.15.1"
"cordova-plugin-camera": "^4.1.0"
Which are the latest versions for as far as I know. I am testing on a samsung galaxy S8.
My code is below:
import { Injectable } from '@angular/core';
import { CameraOptions, Camera, MediaType } from '@ionic-native/camera/ngx';
import { CameraProviderResponse } from '../objects/cameraProviderResponse';
@Injectable()
export class CameraProvider {
constructor(public camera: Camera) {
}
openCamera(selectedMediaType: MediaType, allowedMediaType: MediaType): Promise<CameraProviderResponse> {
const options: CameraOptions = {
sourceType: this.camera.PictureSourceType.SAVEDPHOTOALBUM,
destinationType: this.camera.DestinationType.FILE_URI,
mediaType: selectedMediaType
};
return this.camera.getPicture(options).then((mediaPath) => {
let re = /(?:\.([^.]+))?$/;
let fileExtension = re.exec(mediaPath)[0];
let mediaType;
if (fileExtension === '.jpeg' || fileExtension === '.jpg' || fileExtension === '.png' || fileExtension === '.gif' && (allowedMediaType === MediaType.ALLMEDIA || allowedMediaType === MediaType.PICTURE)) {
mediaType = MediaType.PICTURE;
}
else if (fileExtension === '.mp4' && (allowedMediaType === MediaType.ALLMEDIA || allowedMediaType === MediaType.PICTURE)) {
mediaType = MediaType.VIDEO;
}
else {
return this.openCameraFailed();
}
return {
success: true,
mediaPath: mediaPath,
mediaType: mediaType,
fileExtension: fileExtension
};
}, error => {
return this.openCameraFailed();
}).catch(error => {
console.log(error);
return this.openCameraFailed();
});
}
openCameraFailed(): CameraProviderResponse {
return {
success: false
};
}
}
If you need more information. Please ask.
I currently fixed it like this:
import { Injectable } from '@angular/core';
import { CameraOptions, Camera, MediaType } from '@ionic-native/camera/ngx';
import { CameraProviderResponse } from '../objects/cameraProviderResponse';
import { FilePath } from '@ionic-native/file-path/ngx';
//bug: temp fix stack overflow post: https://stackoverflow.com/questions/58581038/ionic-camera-plugin-file-uri-returning-wrong-filepath?noredirect=1#comment103477183_58581038
@Injectable()
export class CameraProvider {
constructor(public camera: Camera, public filePath: FilePath) {
}
openCamera(selectedMediaType: MediaType, allowedMediaType: MediaType): Promise<CameraProviderResponse> {
const options: CameraOptions = {
sourceType: this.camera.PictureSourceType.SAVEDPHOTOALBUM,
destinationType: this.camera.DestinationType.FILE_URI,
mediaType: selectedMediaType
};
return this.camera.getPicture(options).then((mediaPath) => {
let fileExtension = this.getFileExtension(mediaPath);
if(this.getMediaType(fileExtension) === null) {
return this.filePath.resolveNativePath(mediaPath)
.then(path => {
return this.getCameraProviderResponse(allowedMediaType, path);
})
.catch(err => {
console.log(err);
return this.openCameraFailed();
});
}
else {
return this.getCameraProviderResponse(allowedMediaType, mediaPath);
}
}, error => {
return this.openCameraFailed();
}).catch(error => {
console.log(error);
return this.openCameraFailed();
});
}
getCameraProviderResponse(allowedMediaType: MediaType, path:string) {
let fileExtension = this.getFileExtension(path);
let mediaType = this.getMediaType(fileExtension);
if(mediaType === null) {
return this.openCameraFailed();
}
return {
success: true,
mediaPath: path,
mediaType: mediaType,
fileExtension: fileExtension
};
}
//fix for android
getFileExtension(path: string) {
let re = /(?:\.([^.]+))?$/;
return re.exec(path)[0];
}
//fix for android
getMediaType(fileExtension: string) {
if (fileExtension === '.jpeg' || fileExtension === '.jpg' || fileExtension === '.png' || fileExtension === '.gif') {
return MediaType.PICTURE;
}
else if (fileExtension === '.mp4') {
return MediaType.VIDEO;
}
else return null;
}
openCameraFailed(): CameraProviderResponse {
return {
success: false
};
}
}
It feels a bit hacky but it does the trick for now. Buying me some time to take a closer look at the issue. If I find a better solution I'll post it here as well! In the meantime. If anyone else finds a better solution to this problem, please post it here!