Can't launch PHOTOLIBRARY, Camera launched instead

Hello,
I’ve implemented a popup window that lets a user choose between getting a photo from the camera or gallery. When choosing the camera option the camera loads, but when choosing the photo gallery option the gallery isn’t opened, instead the camera is!

Also if I do take a photo it doesn’t seem to come back as I don’t see the alert(), and the popup doesn’t close. I’ve borrowed code from the ionic camera example to get it to this point. I thought it might be an options problem so I have tried different combinations of Camera.PictureSourceType.PHOTOLIBRARY and navigator.camera.PictureSourceType.PHOTOLIBRARY too but the same issue remains.

Any ideas?

Snippets of code is below:

Photo Controller

.controller('PhotoCtrl', function($scope, $ionicPopup, Camera){

$scope.showPopup = function() {
	   $scope.data = {}
var myPopup = $ionicPopup.show({
    title: 'Add a photo',
    subTitle: 'Choose from Camera or Gallery',
    scope: $scope,
    buttons: [
      {
    	  text: '<i class="icon ion-camera"></i>',
        type: 'button-stable',
        onTap: function(e) {
            $scope.capturePhoto();
            return;
          }
      },
      {
    	  text: '<i class="icon ion-image"></i>',
        type: 'button-stable',
        onTap: function(e) {
        	$scope.chooseFromGallery();
        	return;
          }
      }
    ]
  });
  myPopup.then(function(res) {
    console.log('Tapped!', res);
  });
};

$scope.capturePhoto = function(){
	Camera.getPicture().then(function(imageURI) {
	      console.log(imageURI);
	      alert('got camera photo');
	    }, function(err) {
	      console.err(err);
	    }, {
	      destinationType : Camera.DestinationType.DATA_URL,
	      quality: 75,
	      targetWidth: 320,
	      targetHeight: 320,
	      saveToPhotoAlbum: false
	    });
	
};

$scope.chooseFromGallery = function(){
	Camera.getPicture().then(function(imageURI) {
	      console.log(imageURI);
	  	alert('got photo');
	    }, function(err) {
	      console.err(err);
	    }, {
	      quality: 75,
	      targetWidth: 320,
	      targetHeight: 320,
	      saveToPhotoAlbum: false,
	      destinationType : Camera.DestinationType.DATA_URL,
	      sourceType: Camera.PictureSourceType.PHOTOLIBRARY
	    });
};

})

Camera Factory

  .factory('Camera', ['$q', function($q) {

return {
getPicture: function(options) {
  var q = $q.defer();
  
  navigator.camera.getPicture(function(result) {
    // Do any magic you need
    q.resolve(result);
  }, function(err) {
    q.reject(err);
  }, options);
  
  return q.promise;
}
}
}])

I had a little trouble with Camera.PictureSourceType.* being reliable too, and I ended up using just 1 or 0 to specify, where 0 = Photo Library and 1=Camera.

BTW, you could also probably cut down your code a lot, as you have a lot of duplication between the two methods. It might be better if you had both buttons point to the same function, ie have the ‘Photo’ button call $scope.getImage(1) and the ‘Choose From Gallery’ button call $scope.getImage(0).

Then your getImage() function could be:

$scope.getImage = function(imageSource) {
	Camera.getPicture().then(function(imageURI) {
	      console.log(imageURI);
	  	alert('got photo');
	    }, function(err) {
	      console.err(err);
	    }, {
	      quality: 75,
	      targetWidth: 320,
	      targetHeight: 320,
	      saveToPhotoAlbum: false,
	      destinationType : Camera.DestinationType.DATA_URL,
	      sourceType: imageSource
	    });
};

Because basically the only difference in the two functions is the sourceType attribute.

I went through the exact same process in my latest app. Hope this helps.

Thanks @CyberFerret. I refactored the code (something I would have done anyway later as I’m just playing around at the moment) and used integer values for 1 and 0 into the options but I still get the same behaviour, the camera is launched but not the gallery.

I had some trouble after this with promises not resolving too but I’ve fixed that by getting rid off Camera.DestinationType.DATA_URL and just replacing it with 0. I’m using a Samsung Galaxy Nexus on Android 4.3 if that makes any difference.

Thanks

Controller

.controller('PhotoCtrl', function($scope, $ionicPopup, Camera){

$scope.showPopup = function() {
	   $scope.data = {}
var myPopup = $ionicPopup.show({
    title: 'Add a photo',
    subTitle: 'Choose from Camera or Gallery',
    scope: $scope,
    buttons: [
      {
    	  text: '<i class="icon ion-camera"></i>',
        type: 'button-stable',
        onTap: function(e) {
            $scope.getImage(1);
            return 'done';
          }
      },
      {
    	text: '<i class="icon ion-image"></i>',
        type: 'button-stable',
        onTap: function(e) {
        	$scope.getImage(0);
        	return 'done';
          }
      }
    ]
  });
  myPopup.then(function(res) {
	console.log(res);
  });
};

$scope.getImage = function(source){
	console.log('Source ' + source );
	Camera.getPicture().then(function(imageURI) {
		console.log('got photo: ' + imageURI);
	    }, function(err) {
	    	console.log('error is: ' + err);
	    }, {
	      quality: 75,
	      targetWidth: 320,
	      targetHeight: 320,
	      saveToPhotoAlbum: false,
	      destinationType : 0,
	      sourceType: source
	    });
};

})

Service

.factory('Camera', ['$q', function($q) {

return {
getPicture: function(options) {
  var q = $q.defer();
  
  navigator.camera.getPicture(function(result) {
	  console.log('ok in service ' + result);
    q.resolve(result);
  }, function(err) {
	  console.log('error in service: ' + err);
    q.reject(err);
  }, options);
  
  return q.promise;
}
}
}])

OK, so found the root cause issue all along. Problem was that options weren’t being passed into the service. I guess I figured the fact that the options were on the end of the controller call that somehow they magically got put in somehow.

Final controller code looks like this, service is unchanged. Hope this helps someone! At the very least it’s a cut and paste job for a nifty image selector from the camera or gallery which would be a pretty common request.

.controller('PhotoCtrl', function($scope, $ionicPopup, Camera){

$scope.showPopup = function() {
	   $scope.data = {}
var myPopup = $ionicPopup.show({
    title: 'Add a photo',
    subTitle: 'Choose from Camera or Gallery',
    scope: $scope,
    buttons: [
      {
    	  text: '<i class="icon ion-camera"></i>',
        type: 'button-stable',
        onTap: function(e) {
            $scope.getImage(1);
            return 'done';
          }
      },
      {
    	text: '<i class="icon ion-image"></i>',
        type: 'button-stable',
        onTap: function(e) {
        	$scope.getImage(0);
        	return 'done';
          }
      }
    ]
  });
  myPopup.then(function(res) {
	console.log(res);
  });
};

$scope.getImage = function(source){
	console.log('Source ' + source );
	
	var options = {
		      quality: 75,
		      targetWidth: 320,
		      targetHeight: 320,
		      saveToPhotoAlbum: false,
		      destinationType : 1,
		      sourceType: source
		    };
	
	Camera.getPicture(options).then(function(imageData) {
		console.log('got photo: ' + imageData);
		$("#photo-thumb").attr('src', imageData);
	    }, function(err) {
	    	console.log('error is: ' + err);
	    });
};

})
3 Likes