I am using Cordova 5.3.3 and the Apache Camera Plugin 1.2.0 on IOS 9.
I can succesfully take a picture with the camera however when I try to get a picture from photo library it goes back to camera and I get an error "has no access to assets" in the cordova error callback. I am using the following code.
navigator.camera.getPicture(onSuccess, onFail, {
quality: 75,
destinationType: Camera.DestinationType.DATA_URL,
sourceType : Camera.PictureSourceType.PHOTOLIBRARY
});
When I check the the application rights I see that it has access to Camera but not Photos. Is that the problem? Doesn't Cordova adds the required features when adding the plugin?
I encountered a similar issue when using cordova-plugin-camera
on iOS: permission was not being requested to store the photo in the Photos app after taking a photo, so storing it to the Camera Roll was failing.
I worked around the issue by using cordova-plugin-diagnostic to ensure authorisation was granted for both Camera and Photos before attempting to take a photo. This also takes care of the edge case where the user revokes access after intially granting it. Based on my implementation and your usage of the camera plugin, you could try something like this:
var userMessages = {
noCamera: "The device doesn't have a working camera",
cameraUnauthorized:{
title: "Camera unavailable",
message: "The app is not authorised to access the camera, which means it can't take photos. Would you like to switch to the Settings app to allow access?"
},
cameraRollUnauthorized:{
title: "Photos unavailable",
message: "The app is not authorised to access your Photos, which means it can't take photos. Would you like to switch to the Settings app to allow access?"
},
cameraAuthorisationError:{
title: "Camera authorisation error",
message: "The app could not request access to the camera due to the following error: "
}
};
// Request camera authorisation
checkCameraIsUsable({
successFn: onCameraAuthorised,
errorFn: onCameraAuthorisationError,
requireCameraRoll: true
});
// Called on successful authorisation of camera/camera roll
function onCameraAuthorised(){
navigator.camera.getPicture(onSuccess, onFail, {
quality: 75,
destinationType: Camera.DestinationType.DATA_URL,
sourceType : Camera.PictureSourceType.PHOTOLIBRARY
});
}
// Called on error during authorisation of camera/camera roll
function onCameraAuthorisationError(error){
console.error("An error occurred authorising use of the camera"):
navigator.notification.alert(userMessages.cameraAuthorisationError.message, null, userMessages.cameraAuthorisationError.title);
}
/**
* Checks if camera is available for use; i.e. camera is present and authorized for use.
* If not and authorization has not yet been requested, requests authorization.
* If authorization is denied, informs user and offers to switch to settings page to allow.
* Optionally also checks if camera roll access has been authorized.
* * If not and authorization has not yet been requested, requests authorization.
* If authorization is denied, informs user and offers to switch to settings page to allow.
*
* @param {Object} params - parameters:
* <ul>
* <li>{Function} successFn - callback to invoke if camera is available for use.</li>
* <li>{Function} errorFn - callback to to invoke if camera is unavailable for use. The function will be passed a single {String} argument which contains the error message.</li>
* <li>{Boolean} requireCameraRoll (optional) - if true, checks for/requests camera roll authorization. Defaults to false.</li>
* </ul>
*/
function checkCameraIsUsable(params){
function requestCameraRollAuthorization(){
cordova.plugins.diagnostic.requestCameraRollAuthorization(function(granted){
if(granted){
params.successFn();
}else{
onCameraRollAuthorizationDenied();
}
}, params.errorFn);
}
function onCameraRollAuthorizationDenied(){
navigator.notification.confirm(
userMessages.cameraRollUnauthorized.message,
function(i){
if(i==1){
cordova.plugins.diagnostic.switchToSettings();
}
},
userMessages.cameraRollUnauthorized.title,
["Yes","No"]
);
}
function getCameraRollAuthorizationStatus(){
cordova.plugins.diagnostic.getCameraRollAuthorizationStatus(function(status){
switch(status){
case "denied":
onCameraRollAuthorizationDenied();
break;
case "not_determined":
requestCameraRollAuthorization();
break;
default:
params.successFn();
}
}, params.errorFn);
}
function requestCameraAuthorization(){
cordova.plugins.diagnostic.requestCameraAuthorization(function(granted){
if(granted){
if(params.requireCameraRoll){
getCameraRollAuthorizationStatus();
}else{
params.successFn();
}
}else{
onCameraAuthorizationDenied();
}
}, params.errorFn);
}
function onCameraAuthorizationDenied(){
navigator.notification.confirm(
userMessages.cameraUnauthorized.message,
function(i){
if(i==1){
cordova.plugins.diagnostic.switchToSettings();
}
},
userMessages.cameraUnauthorized.title,
["Yes","No"]
);
}
function getCameraAuthorizationStatus(){
cordova.plugins.diagnostic.getCameraAuthorizationStatus(function(status){
switch(status){
case "denied":
onCameraAuthorizationDenied();
break;
case "not_determined":
requestCameraAuthorization();
break;
default:
if(params.requireCameraRoll){
getCameraRollAuthorizationStatus();
}else{
params.successFn();
}
}
}, params.errorFn);
}
function isCameraPresent(){
cordova.plugins.diagnostic.isCameraPresent(function(present){
if(present){
getCameraAuthorizationStatus();
}else{
params.errorFn(userMessages.noCamera);
}
}, params.errorFn);
}
isCameraPresent();
};