One of the most commonly used PhoneGap API’s is the Camera API. In the age of the selfie, a phones camera is one of the most commonly used functions of the device – naturally, a lot of apps integrate with this.
It’s simple enough to trigger the devices camera and grab the resulting photo, but there’s one big problem. The photo will eventually disappear. I’m not sure on the exact timeframe, but you can probably kiss your photos goodbye after a few days.
Any photos that are taken using the Camera API are stored in a temporary folder, and after a little while the file will be deleted. This is fine if your app is uploading the picture to a server or otherwise only needs to display the photo temporarily, but if you want to permanently store the photo within your application by referencing its File URI (the location of the photo on the device) you’re going to run into some trouble.
The way to solve this problem is to move the file into permanent storage with PhoneGap’s File API after you take the photo, and then reference that URI within your application instead. This makes the process a bit more tricky though so I’ll show you how to do it step by step.
I’ll be using Ionic’s ngCordova to implement the Camera functionality, which adds a few bells and whistles to make things easier, but you could easily adapt this to use any other framework by referencing the PhoneGap Camera and File API’s in the documentation. If you want some help, you can download an example file further down in this post of a plain PhoneGap implementation (there’s quite a bit more code involved than the ngCordova implementation).
1. Include the plugins in your project
First make sure that you include the Camera and File plugins in your project. If you are using a local version of PhoneGap or ngCordova you will need to run:
cordova plugin add org.apache.cordova.camera
and
cordova plugin add org.apache.cordova.file
If you are using PhoneGap Build you will need to include the plugins in your config.xml file:
<gap:plugin name="org.apache.cordova.file" />
<gap:plugin name="org.apache.cordova.camera" />
2. Trigger the getPicture() method
When using ngCordova, we can use the getPicture() method to activate the devices camera and return a photo. The implementation will look something like this:
var options = {
quality: 100,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
cameraDirection: 1,
saveToPhotoAlbum: true,
};
$cordovaCamera.getPicture(options).then(
function (imagePath) {
//Success
},
function (error) {
//An error occured
}
);
This will trigger the camera to launch and once the photo is taken we can do whatever we want with the resulting data, which in this case is a path to the image on the device. Typically you might inject that path into an img element, or save it somewhere to display later.
Notice that we are also supplying an options array, this specifies how the camera should behave. In this case I’m saying that I want to receive a File URI as the result, it should use the camera to take a photo, it should return a JPEG image, the front facing camera should be used and a copy of the photo should also be saved tot he users photo album.
For a full list of options see the camera documentation.
NOTE: Remember, if you’re using ngCordova then you need to make sure you require the plugins you need in your controller, i.e:
.controller('MyControllers', function($scope, $cordovaCamera, $cordovaFile){
})
3. Move the file to permanent storage
With the above code we’ve managed to successfully capture a photo and retrieve its file path. It’s only stored in a temporary directory that will eventually be wiped though, so now we need to move it.
You will need to add some additional code that makes use of the File API within the callback function for the Camera. It should look something like this:
$cordovaCamera.getPicture(options).then(
function (imagePath) {
//Grab the file name of the photo in the temporary directory
var currentName = imagePath.replace(/^.*[\/]/, '');
//Create a new name for the photo
var d = new Date(),
n = d.getTime(),
newFileName = n + '.jpg';
//Move the file to permanent storage
$cordovaFile
.moveFile(
cordova.file.tempDirectory,
currentName,
cordova.file.dataDirectory,
newFileName
)
.then(
function (success) {
//success.nativeURL will contain the path to the photo in permanent storage, do whatever you wish with it, e.g:
//createPhoto(success.nativeURL);
},
function (error) {
//an error occured
}
);
},
function (error) {
//An error occured
}
);
What we’re doing in the code above is getting the current directory and file name, and moving it to a new directory with a new file name.
We use the date to create the file name so that each new photo taken will have a unique name, if you just kept the original name then it would overwrite previous photos that were taken.
You can use the success.nativeURL value to do whatever you want with the resulting photo, this will be the path to the photo in permanent storage.
If you’re having any trouble, be sure to leave a comment below!