Camera shooting fails 20% of the time

var camera = { settings : { quality : 50, targetWidth : 1024, targetHeight : 1024, correctOrientation : true } }; var error = function(message) { alert("Error happened while trying to get a picture", message); }; document.addEventListener("deviceready", function() { camera.toFile = function() { this.settings.destinationType = navigator.camera.DestinationType.FILE_URI; return this; }, camera.toBase64 = function() { this.settings.destinationType = navigator.camera.DestinationType.DATA_URL; return this; }, camera.fromCamera = function() { this.settings.sourceType = navigator.camera.PictureSourceType.CAMERA; return this; }; camera.fromLibrary = function() { this.settings.sourceType = navigator.camera.PictureSourceType.PHOTOLIBRARY; return this; }; camera.fromPhotoAlbum = function() { this.settings.sourceType = navigator.camera.PictureSourceType.SAVEDPHOTOALBUM; return this; } camera.get = function(callback) { navigator.camera.getPicture(function(data) { alert("taking a picture successful"); callback(data); }, error, camera.settings); }; }, false); 

This is my little camera wrap. And I call it this way:

 camera.fromPhotoAlbum().toBase64().get(function(base64){}); 

In approximately 20% of cases, there is a β€œwarning (β€œ photographing completed successfully ”); it is not called until an error is displayed. If I canceled the shooting, a warning message will appear with the messageβ€œ Error while trying to get the image ”, so the error callback works.

In principle, nothing happens. I tested it on a Samsung Galaxy S2 on CM9 and the all-new HTC One X.

+4
source share
1 answer

Recently there was another question about the same problem that I answered. We ran into this at my company and decided. This has more to do with Android than with Phonegap.

What happens when you start the camera, your application switches to onStop (). While there, the Android system has the right to kill your application if it needs memory. It so happened that the memory usually becomes low when the camera takes a picture and uploads it to memory, so there is a good chance that your application will be killed while your user takes the picture.

Now that your application is dead, when the camera ends, it restarts your application. That is why it is so strange; the camera returns to your application, but not the same instance as before, so your callback is never called because it no longer exists.

You can reduce the frequency with which this happens by reducing the image quality and passing its URI instead of data to your application, but the problem will not completely disappear.

To get around the callback never happened, we made a Java callback that starts the camera and saves the image in the same place every time it is needed. Then, when the application begins to recover from the kill, it looks in that place for the image.

This is a strange solution to a stupid problem, but if your application gets killed, this camera callback just won't happen. If you need more information on how to make a Java callback, do this, let me know and I will put the code here. Otherwise, review this "SO" answer for more information.

EDIT: here is the code we use in our main activity of DroidGap:

 private static final String folderPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/appName"; private static final String filePath = "phonegapImage.jpg"; @Override public void onCreate(Bundle savedState) { //...The rest of onCreate, this makes the Java available in JavaScript appView.addJavascriptInterface(this, "Camera"); } public void takePhoto(final String callback) { Log.v("Camera Plugin", "Starting takePhoto callback"); Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(folderPath, filePath))); startActivityForResult(intent, TAKE_PICTURE); } public String getPhotoUri() { return Uri.fromFile(new File(folderPath, filePath)).toString(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case TAKE_PICTURE: if (resultCode == Activity.RESULT_OK) { //Do whatever you need to do when the camera returns //This is after the picture is already saved, we return to the page } break; default: Log.v("Camera", "Something strange happened..."); break; } } 

Then in your JavaScript you can call the camera with:

 Camera.takePhoto("onPhotoURISuccess"); //Then, to get the location of the photo after you take it and load the page again var imgPath = Camera.getPhotoUri(); 

So, this is about it. Just remember to change all the path / file / page / etc names to what you want to use in your application. This will overwrite this image every time you take it, but you can probably learn something to dynamically name them if you don't want to. You can use this URI just like any other path in your JavaScript.

+11
source

All Articles