Monday, July 2, 2012

Change to Camera code in PhoneGap 1.9.0

With the release of PhoneGap 1.9.0 I've checked in some improvements to the Camera.getPicture() functionality. First a bit of an explanation as to why there are so many issues with the Camera code.

One of the major causes of issues is that as new devices get released the cameras in them get better and better allowing you to take very high resolution images. Now when you specify a few parameters to our getPicture method like quality or targetWidth/targetHeight you can get out of memory errors. Why do you get out of memory errors you ask? Well in my honest opinion it is because Android does a real poor job of handling Bitmaps. In order to do any manipulation on an image like scaling or compression you need to load the entire image into memory.

Let's take a look at a real world example. My Samsung Galaxy Note has an 8MP camera with a resolution of 3264 by 2448. So in memory that picture assuming ARGB_8888 will be:

3264 pixels x 2448 pixels x 4 bytes/pixel = approximately 30 megabytes 

Let that sink in, approximately 30 megabytes. Considering that I read somewhere the default heap size for an app running in Dalvik is 48 megabytes you can see how you can quickly run out of memory taking pictures.

Fixing the Best Case Scenario 

I've added some code to detect the best case scenario and not load the image into memory. Here is the getPicture method to call if you want to use the best case all the time.
var options = {
    quality: 100,
    destinationType : navigator.camera.DestinationType.FILE_URI,
    sourceType: navigator.camera.PictureSourceType.CAMERA,
    encodingType: navigator.camera.EncodingType.JPEG,
  }
  navigator.camera.getPicture(win, fail, options);
The important part about the options is that you specify a quality of 100. This along with accepting the default width and height will skip the need to load the image in memory.

Reducing Memory when using targetWidth/targetHeight

Okay but if you do specify a targetWidth/targetHeight the image has to be loaded into memory. Now we do a bit of math to figure out the smallest multiple of the image that can be loaded that isn't smaller than the requested width and height. You see the Bitmap.createScaledBitmap() method allows you to specify that the bitmap be load at half, quarter, etc. size. Now if you request a 900x900 image from a 2000x2000 original image it will be loaded into memory as 1000x1000 and scaled from that point. It saves about 11 megabytes of memory doing it this way.

Respects the saveToPhotoAlbum option

Up until 1.9.0 each picture taken automatically gets added to the Android photo album/gallery. As of 1.9.0 if you want that type of behaviour to continue you need to set this option to true as the default is false.

Respects the correctOrientation option

One of the other big problems with our Camera functionality is that pictures taken in portrait mode were always displayed on their side when you attempted to view them in your app. Remember your app is based off of a WebView and the web view does not care about the exif orientation parameter. Now if correctOrientation is set to true we rotate the image so that it will show up properly in the WebView and we reset the orientation parameter to normal so it'll show up properly in desktop image viewers.

If you run into problems using the Camera in 1.9.0 please raise a bug on JIRA and give a detailed  reproduction scenario. I want to make sure this functionality is rock solid for the upcoming 2.0.0 release.

115 comments:

  1. There's no stopping Simon it seems! :) Well done and thanks.

    ReplyDelete
  2. Thanks, but I have problem about display photo and send it to server.

    path return "file:///data/data/com.xxx.xxxx/.Pic.jpg?12345678" in 1.9


    img src="path" cannot display

    but I can display and send the photo using path in 1.8.1

    path return content://media/external/images/media/xxxx
    in 1.8.1


    my problem same as following link:
    https://groups.google.com/group/phonegap/browse_thread/thread/b580a165da9a64b2/ad4749e9a55bb716?lnk=raot

    ReplyDelete
  3. Hi Simon,

    Hope you are doing well

    I have a query if you can help me.

    I am using phonegap 1.3 and created Android plugin with the help of the document given http://tinyurl.com/42sa79b . Now I am trying to update to Phonegap 1.9 but it is giving me an error that
    import com.phonegap.api.PluginResult.Status;
    Status in the above statement cant be resolved. I have read the documentation of phonegap 1.9 release and it says that some of the Android plugin will not work properly.

    Please help me and provide some suggestions why it is not working?

    Thanks in advance
    Summved

    ReplyDelete
  4. @Summved Jain

    Just change references to "com.phonegap" to "org.apache.cordova" as the package of the classes has changed.

    ReplyDelete
  5. @steve-c

    Yeah, if you set saveToPhotoAlbum to true in your options it will get back to providing you the content:// type uri. There is no reason why you shouldn't be able to see the image in your own /data/data directory. I've put in a small fix for this issue and I'll post to the PG group thread where you can pick up a jar to test.

    ReplyDelete
  6. Thanks Simon,

    Could you please also let me know what does cordova means here? Is the name has changed from phonegap to Cordova?


    Summved

    ReplyDelete
  7. @Summved Jain

    Yes, the name has changed. We moved the project to Apache for safe keeping so the package name of the Java classes changed.

    ReplyDelete
  8. Great article, but it didn't stop crashing the app with me.
    Now it doesn't crash when taking a picture, but when choosing a picture from your folders, it still crashes.

    My settings:

    quality: 100,
    destinationType: navigator.camera.DestinationType.FILE_URI,
    sourceType: source,
    encodingType: navigator.camera.EncodingType.JPEG


    On success, I put the imageURI to another variable, and then I have another button to send the image.
    It crashes after choosing the picture, so I think it doesn't have anything to do with the sending etc.

    http://pastebin.com/4LBNGxdz
    This is my full code at the moment.

    ReplyDelete
  9. @admins

    The code you are using looks fine but what I really need to see is the error. Can you run "adb logcat" so I can see what is going on?

    ReplyDelete
  10. Thanks for the prompt answer Simon!

    http://pastebin.com/xmR7Lurx
    I pasted the whole LogCat error log there. I hope you can figure out something!

    ReplyDelete
  11. @admins

    O I C

    You are running into an OutOfMemory error when trying to load the image. I think I can do something about this. Please stand by. I may be able to post a .jar for you to test. in 30 minutes.

    ReplyDelete
  12. @admins

    Please grab a patched jar from:

    https://dl.dropbox.com/u/887989/cordova-1.9.0.jar

    It should fix the out of memory error you are getting. Let me know what you find and then I'll check in the fix.

    ReplyDelete
  13. Thank you so much!
    That completely fixed my problem :)

    Do you happen to know why the pictures appear sideways when I upload them? This seems to be a usual problem with image uploaders in Android, so I'd like it fixed in my app :P

    ReplyDelete
  14. Thanks Simon,

    That was really helpful. Thanks for your prompt reply.

    Could you please guide me with some tutorials or books to learn phonegap and JQuery mobile.

    Kind Regards,
    Summved

    ReplyDelete
  15. @admins

    I've just checked in the fix.

    If you are having orientation problems it is probably because you are taking the picture in portrait mode while most phones expect you to take it in landscape more. You can try setting correctOrientation to true when you use getPicture().

    ReplyDelete
  16. @Summved Jain

    I don't do jQuery Mobile. I haven't found it to be very good on Android. Look at using Sencha Touch or Dojo Mobile instead.

    To learn more about PhoneGap besides my blog posts there are:

    http://phonegap.com/blog
    http://www.amazon.com/Recipes-Programming-PhoneGap-Cross-Platform-Development/dp/1449319548/ref=sr_1_1?ie=UTF8&qid=1341592909&sr=8-1&keywords=phonegap
    http://www.amazon.com/PhoneGap-Essentials-Building-Cross-Platform-Mobile/dp/0321814290/ref=sr_1_3?ie=UTF8&qid=1341592909&sr=8-3&keywords=phonegap
    http://www.amazon.com/PhoneGap-Essentials-Building-Cross-Platform-Mobile/dp/0321814290/ref=sr_1_3?ie=UTF8&qid=1341592909&sr=8-3&keywords=phonegap

    ReplyDelete
  17. Hello Simon,

    Sorry to bother you again.
    Could you please help me with the below query?

    I'm using Phonegap to develop my application and I'm trying to get the app to list files on the sdcard. But only specific files, for example mp3 or my own file format. I've been trying to use the Phonegap API as it seems to have a directory reader action, but I don't know how to use it.

    Kind Regards,
    Summved

    ReplyDelete
  18. @Summved Jain

    Take a look at this thread. You'll need to check to see if the name of the file ends with .mp3 but other than that the code is written for you.

    https://groups.google.com/d/msg/phonegap/jsMF9Qf4918/E9T2g3UsV5YJ

    ReplyDelete
  19. Thanks so much

    That was really helpful. Let me test this and will update you.

    Kind Regards,
    Summved

    ReplyDelete
  20. Hi again, Simon.

    It seemed that it worked at first, but when I now test to take a picture with camera, it's crashing.

    http://pastebin.com/4UmCmiqq
    This is the error log again.

    Selecting the image from gallery works fine, but taking a new picture crashes the program.

    When I first contacted you, selecting a picture crashed, while taking a picture didn't. So this is the opposite of the previous problem.

    ReplyDelete
  21. Update to the comment before, it crashes randomly when selecting a image from gallery too :/

    http://pastebin.com/6pMstMn0

    ReplyDelete
  22. @admins

    It looks like it ran out of memory trying to correct the orientation of the picture. What options are you using when calling getPicture from the camera? Are you taking the picture in portrait mode? How good is the camera resolution? You may want to try the same test with correctiOrientaiton set to false.

    Basically, I'm trying my hardest to keep memory usage down but Android handles images really poorly.

    ReplyDelete
  23. Hey,

    I know that it's Android problem, but it seems that you're the one and only person I could contact now.
    I'm glad that you still try to figure the problems, even though it's hard.

    I'm using Samsung Galaxy S II and camera is 8MP and images 3264x2448.

    It really seems that it works when I set correctOrientation to false.
    I'm taking pictures in portrait mode.

    At the moment, I'm taking pictures with these settings:
    { quality: 100, destinationType: navigator.camera.DestinationType.FILE_URI, sourceType: source, encodingType: navigator.camera.EncodingType.JPEG, correctOrientation: false }

    Source is user's choice, you can select between navigator.camera.PictureSourceType.PHOTOLIBRARY/CAMERA

    ReplyDelete
  24. @admins

    Yeah, that is the same resolution as my Samsung Note. That means the image in memory is about 31 megabytes and then the secondary image to hold the rotation data is another 31 megabytes and boom! Out of memory error.

    It looks like we'll need to write our own image manipulation code to get around this issue but that's not going to happen this morning. I wish but other duties call.

    In the mean time try requesting a smaller targetWidth and targetHeight will save on memory usage. That might not fit the use case for your app but at least it'll get around most crashes for now.

    Talk to you soon.

    ReplyDelete
  25. Hi Simon,

    Just wondering, do you happen to know of any good way of retaining the exif data once you've resized an image?

    The ones I seem to lose are, well, all of them, but I'm trying to retain the ones related to the datetime of when the image was created and the gps lang and long co-ordinates...Idea is that someone can upload the image at some point in the future and it'll put itself nicely where they took the picture and when, if you see what I mean.

    Thanks in advance :)

    ReplyDelete
  26. the application crashes when trying to access image from es file explorer in android using phonegap camera photolibrary source. can u suggest some solution.

    ReplyDelete
  27. @Duncan

    The only way for the EXIF info not to be touched is to specify a quality of 100 and a destination of FILE_URI. Don't use any other parameters as that will cause the file to get re-written. I can only keep the following EXIF information as that is what the SDK will allow me to access:

    https://developer.android.com/reference/android/media/ExifInterface.html

    GPS and Datetime should stick around. They do on my Samsung phone.

    ReplyDelete
  28. @Roshan Chaudhary

    Use the Gallery app instead. Open an issue on JIRA:

    https://issues.apache.org/jira/browse/CB

    and include "adb logcat" so I can see what is going on.

    ReplyDelete
  29. Hi simon ... very nice post.
    I tell you my scenario.

    Mobile: LG3 with Android 4.0
    Using PhoneGap 1.9.0
    Using this function:

    navigator.camera.getPicture(onPhotoDataSuccess, onFail,
    {
    quality: 80,
    destinationType: destinationType.FILE_URI,
    encodingType: navigator.camera.EncodingType.JPEG,
    mediaType: 0,
    targetWidth: 1024,
    targetHeight: 768,
    correctOrientation: false
    }
    );

    Taking the first picture gives no problem. After second photo, logcat gives this:
    http://pastebin.com/WJ2KTBh4
    and app is closed.

    As you can see I'm using library, no orientation, slow resolution, slow quality ...

    Any ideas ?

    THANK YOU in advance

    ReplyDelete
  30. Hi Simon,

    I am using Camera API with Cordova 1.8.1 but not able to make it work. The same code works with phonegap 1.3.0. The API is not returning the base64 of the image. It returns some text that says "content://media/external/images/media/373". The number 373 is changing everytime when camera clicks. Check the code below: -

    navigator.camera.getPicture(onCameraSuccess, onError, { quality: 50, destinationType: Camera.DestinationType.FILE_URL });

    function onCameraSuccess(imagedata) {
    alert(imagedata);
    }

    This alert shows the above text in case of 1.8.1 and shows the base64 in case of 1.3.0

    Please help me on this as this is on priority

    Kind Regards,
    Summved

    ReplyDelete
  31. @Summved Jain

    You are getting a FILE_URI because that is what you specify in your getPicture command. Change FILE_URI to DATA_URL and you will get a base64 encoded image.

    ReplyDelete
  32. Hi Simon,

    Thank you so much
    It is working fine. Could you please let me know when I click the picture using the API, it stores in phone sd card but when I try to look at that picture, it doesnt show up. It says preview not available and you can not see that image even when you copy it to your computer.

    Kind Regards,
    Summved

    ReplyDelete
  33. @Summved Jain

    Sorry, I don't understand what you are asking. Please provide more details over at:

    http://www.formspring.me/macdonst

    ReplyDelete
  34. @alex

    Looking at the stack trace it is an out of memory error. Which I can't do much about. What is the quality of your camera? That is what is the native resolution?

    ReplyDelete
  35. Hi,

    We have implemented the camera capture function in our app with phonegap 1.9 and using it on 30+ device for 30 people. We have specified targetWidth and height of 640 x 800. Most of the time the app works perfectly. But occasionally and randomly we would get thumbnail size photos from the capture function. This is bugging me a lot since we can not reproduce it everytime. We are using Galaxy Tab original with 2.2 and S3 and some Galaxy Notes. And it happens for all the devices on a random basis.

    Just wanted to find out if anyone experienced any issues like this. Looks to me that the image we get is the thumbnail image.

    Thanks,

    Sazzad

    ReplyDelete
  36. @Sazzad-Hossain

    This is the first I've heard of this type of bug. Can you please open an issue on JIRA?

    https://issues.apache.org/jira/browse/CB

    Provide as many details as you can and logs are always good.

    ReplyDelete
  37. Hi Simon,

    i am using cordova 2.0,in some phones camera.getPicture() directly opens the image gallery but in some it gives an option either to open image gallery or file explorer, if i open file explorer and select a non image file my app crashes saying application not responding.please help.
    Thanks,
    Megha

    ReplyDelete
  38. @megha rathore

    I believe I've fixed all those bugs in 2.1.0 as part of this issue:

    https://issues.apache.org/jira/browse/CB-1293

    ReplyDelete
  39. Hi Simon,
    Thanks for your prompt reply,by the way when will cordova 2.1.0 be released? as we need to fix this bug asap and send the release to client in three days.
    Thanks
    Megha Rathore

    ReplyDelete
  40. @megha rathore

    Well we are going through the voting process of getting from incubator to full fledged Apache project. The whole process has taken much longer than I excepted so I hate to comment on a date but I hope to see it early next week.

    ReplyDelete
  41. Hey Simon,

    in regard with my previous query i updated my phonegap with the latest release(2.1) and found that my app still crashes if i select a non image file (say an audio file or a js file) giving me a message that sorry Unfortunately (my_app_name) has stopped working. :(

    Megha Rathore

    ReplyDelete
  42. @Megha Rathore

    Okay, what app are you using to select the non-image file? Can you post up the crash in "adb logcat" on gist or pastebin so I can see it?

    ReplyDelete
  43. Hi Simon,

    The app which i am using for selecting a non image file is ES File Explorer (Google market), you can checkout my "adb logcat" here-
    https://gist.github.com/3786334

    Thanks
    Megha

    ReplyDelete
  44. @Megha Rathore

    Cool, I will try to reproduce.

    ReplyDelete
  45. @Megha Rathore

    Cool, I will try to reproduce.

    ReplyDelete
  46. @Megha Rathore

    The normal way works for me but the file way crashes the app. I just checked in a fix to guard against the ES File Explorer returning things the "file way".

    Honestly looking at your stack trace it appears you are still using the old 2.0.0 jar file.

    ReplyDelete
  47. Hey Simon,
    Thanks again for your quick reply, and yeah i am sorry by mistake i sent you the wrong stack trace(2.0), but anyway the same problem is showing up on 2.1.0 as well.
    from where can i checkout your fix by the way?
    Thanks
    Megha

    ReplyDelete
  48. @Megha Rathore

    Can you show me the stack trace from the 2.1.0 run? It shouldn't be the same at all. If you want to grab the fix it has been checked in to:

    https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=summary

    ReplyDelete
  49. Hey Simon,

    Thanks a lot for the fix, i will try it out and let you know. :)
    and here is the error log from cordova 2.1.0 run

    https://gist.github.com/3798252

    Thanks
    Megha

    ReplyDelete
  50. Hey Simon,

    Just wanted to add that for me app crashes either ways( file way as well as normal way), here is the error log from the run of cordova 2.1.0

    https://gist.github.com/3798393

    Thanks
    Megha

    ReplyDelete
  51. @megha rathore

    Okay, it is the same error. I think I need a more detailed test case as I'm missing out on the problem. So you use ES File Explorer to get the image and it does matter which option you pick from the dialog. I guess it must be something in the options you are sending to getPicture() that I'm not accounting for. Can you send me the line you use for getPicture with all the options you use?

    ReplyDelete
  52. Hey Simon,

    here is what i am using

    navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 100,
    destinationType: destinationType.DATA_URL,
    sourceType: source,
    targetWidth: 65,
    targetHeight: 65
    });


    Thanks
    Megha

    ReplyDelete
  53. @megha rathore

    Oh, a DATA_URL, never thought to test that. I will give it another try.

    ReplyDelete
  54. @megha rathore

    Wow, don't know why DATA_URL made a difference but it did and I reproduced then fixed the bug. It'll be in 2.2.0.

    ReplyDelete
  55. @megha rathore

    Wow, don't know why DATA_URL made a difference but it did and I reproduced then fixed the bug. It'll be in 2.2.0.

    ReplyDelete
  56. Hey Simon,

    Thanks a lot :) now waiting for cordova 2.2.0

    Thanks
    Megha

    ReplyDelete
  57. Hey Simon,
    Can i ask you for the patch required to solve my problem?(PG crash on using DATA_URL for non image files), need it urgently.
    Thanks
    Megha Rathore

    ReplyDelete
  58. @megha rathore

    You can grab the latest source from:

    https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=summary

    and build it yourself. Alternatively we are tagging 2.2.0rc1 on Friday so a release candidate binary should be posted on PhoneGap.com early next week.

    ReplyDelete
  59. Hi simon,
    we are having an serious issue that needs to be fixed ASAP.Please do help us.Using cordova 2.1.0, we face the app getting closed when taking a picture from camera and pressing ok button... what is the real problem here?

    ReplyDelete
  60. @vivek s

    Not enough info. What do you see in "adb logcat"?

    ReplyDelete
  61. Hi Simon,

    I'm running out of options with a camera bug.
    Device: Samsung Galaxy s2
    Android: 4.0.4
    Phonegap: 2.0.0

    The camera crashes the whole application when I click save.

    I couldn't find a MemoryOutOfBounds error which I had with the 1.8.0, but the behaviour of the camera is the same.

    call after deviceready:

    https://friendpaste.com/2CRvGWUP2BPYF3k4nIYbFC

    Adb logcat:

    https://friendpaste.com/2CRvGWUP2BPYF3k4nIYcTC

    ReplyDelete
  62. @Susanna

    What Camera app are you using? I'm seeing a weird return value for the requestCode.

    ReplyDelete
  63. @Simon I'm using the default one, Camera version 1.0

    ReplyDelete
  64. @ Simon

    and as additional info, the log of a test run with taking only black pictures. I managed to get the crash after 5 pictures.

    adb logcat:
    https://friendpaste.com/2CRvGWUP2BPYF3k4nIpY9j

    ReplyDelete
  65. @Susanna

    I'm at a loss to explain what is going on. When you say it crashes do you mean the application restarts? If so the app may be cleared up by the OS while you are in the Camera app to reduce memory usage.

    ReplyDelete
  66. @Simon

    So the application closes completely. It happens between navigator.camera.getPicture and the success callback. So I get the console logs before and after navigator.camera.getPicture but never the one at the first line of success callback when the app crashes.

    ReplyDelete
  67. @ Simon

    Solved the problem.

    and it was:

    adding this to android manifest
    android:configChanges="orientation|screenSize|keyboardHidden"
    AND
    because the application is using backbone I navigate on success to the same page I came from through the router.

    Before I just saved the image to a model and through a change in the model rendered the view again.

    I still don't throughly understand why, but hey, it works!

    and thanks, "If so the app may be cleared up by the OS while you are in the Camera app to reduce memory usage." led me to the right track :D

    ReplyDelete
  68. @Susanna

    ARG!!! Sorry, I should have suggested that earlier. It is a basic step in setting up your PhoneGap app. Without the orientation change Android will restart you app if you switch from portrait to landscape and since you are probably in portrait mode int the app then landscape mode for the camera it all makes sense.

    ReplyDelete
  69. Hi Simon,
    I have an issue when I try to take a picture in my phonegap application.
    The picture saved in the Camera folder (Nexus 7 or Samsung Galaxy) seems to be corrupted: the file size is equal to 0kb.

    However I can see the picture browsing the gallery on my phone.

    I tried a simple project with different options but I didn't find any solution to get a picture saved with its right size.

    Here is the javascript code used to take the picture:

    destinationType: Camera.DestinationType.FILE_URI,
    quality: 100,
    allowEdit: false,
    correctOrientation: false,
    saveToPhotoAlbum: true

    (sdk 11, 15 or 16)

    ReplyDelete
  70. @Simon, no problem. I was the idiot just going android:screenOrientation="portrait"

    but still, just adding the orientation change was not enough for the problem to be fixed.

    Something with the models and views. However thanks a million times :)

    ReplyDelete
  71. @Julien B

    Hmmm...can you head over to:

    https://issues.apache.org/jira/browse/CB

    and raise an issue? This seems to be a bug but I'd rather collect logs, etc. over there.

    ReplyDelete
  72. Hi Simon.

    I have used getPicture successfully on my Galaxy Note running Cordova 2.0, but it has stopped working and I can't figure out why.

    The symptoms are 'Camera cancelled.' error. I can't see any memory errors in the logcat output.

    I have cut it down to a simple test case, and its still failing, here is the code:-

    http://pastebin.com/UpyefMmZ

    And the logcat output:-

    http://pastebin.com/X4K0YvKU

    One thing that caught my eye in the logcat shortly after calling getPicture was the line:

    W/ActivityManager( 1854): Activity is launching as a new task, so cancelling activity result.

    I wondered if this could be a project manifest setting that is causing the problem. My activity has the following options set

    android:name=".RMCv2dev"
    android:label="@string/title_activity_rmcv2dev"
    android:configChanges="orientation|keyboardHidden|screenSize"
    android:screenOrientation="portrait"
    android:alwaysRetainTaskState="true"
    android:launchMode="singleInstance"
    android:hardwareAccelerated="true"

    At the moment I am at a loss as to why the camera code has stopped working.

    ReplyDelete
  73. @Simon

    I resolved my camera issue. I determined that the the problem was in my activity configuration in my manifest, which had

    android:launchMode="singleInstance"

    Is there any reason why this should option affect the camera? I had added it because I was sometimes getting multiple instances of my app running, which I don't want either.

    ReplyDelete
  74. Hi Simon!

    After testing this on Android 4.1.2 with Cordova 2.2.0, I have doubts, that your optimization for the "best case scenario" still works.

    These are my observations on a Samsung Galaxy SII :

    (using the options in your post) --> screen freezes ,after 8MP image was taken and control is passed back to my app. Heap grows by 31961104 bytes.

    (extending your options by targetWidth and targetHeight ; 1000px) --> works as expected. Heap grows by 7990288, then by 3000016 bytes.

    Now I don't know if anything significant has changed since your post, or if I am doing things wrong.

    Should I post this as an issue?

    ReplyDelete

  75. Post its amazing Simon. Please have a look at my error, im have been trying almost everything its to fix the camera Crash, but nothing works for me.

    http://pastebin.com/mCv95469

    quality: 100,
    destinationType : navigator.camera.DestinationType.FILE_URI,
    sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY,
    encodingType: navigator.camera.EncodingType.JPEG,
    correctOrientation: false,
    targetWidth: 1024,
    targetHeight: 768

    ReplyDelete
  76. @Sandeep Narwal

    There is nothing in that log that indicates a crash. I think you may have sent me the wrong link.

    ReplyDelete
  77. Hello Simon,

    Thanks for the great work (blog, plugins, phonegap etc)!

    I'm having a problem that some others already complain. The camera restarts my app 90% of times.

    I'm using Phonegap 2.2.0 on android 2.3.4 and 4.0.4.
    I have the "android:configChanges="orientation|keyboardHidden" on my android manifest.
    I have tried your tips from this post.

    Here is a log: http://pastebin.com/Xp5yE9s3

    I can't identify a memory problem. The app is killed before a took the picture.

    Can you help me?

    Thanks!

    ReplyDelete
  78. @Hugo Maia Vieira

    What camera app are you using? I see that there is an error popping up from the C code. Have you tried a different camera app?

    ReplyDelete
  79. Hi Simon in certain phones i can access photo but not in other albums get error aS UNDEFINED .Im using photo library option and not savedtophotoalbum.How do i solve this problem in order to access photos

    ReplyDelete
  80. @Rahul Mendonca

    Can you provide me with more details?

    ReplyDelete
  81. Simon, I'm using the default camera app. After I install another camera app (http://migre.me/cz3IN) the problem stops with both camera apps.

    But this is happening with some users of my app, with different andoid versions and phones models.

    There is anything I can do?

    ReplyDelete
  82. @Hugo Maia Vieira

    You didn't really explain what problem you are running into. Also if you've found a solution by installing a 3rd party app that's great news.

    ReplyDelete
  83. Hi Simon,

    I used this code to capture image in my application

    navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 100,
    destinationType: navigator.camera.DestinationType.FILE_URI,
    saveToPhotoAlbum: true,
    correctOrientation: true,targetWidth: 100,
    targetHeight: 100 });


    its working. but every time i capture the image, my application size increases for 2MB each time.I think it is storing somewhere along with the application. how to solve this?


    Thanks,

    ReplyDelete
  84. @niranjana devi

    Well each picture is initial saved in your apps temp directory and it is called ".Pic.jpg". The image name is reused each time you take a picture so it shouldn't continue to increase after the first picture taken.

    ReplyDelete
  85. hello! , Simon Mac,sorry to troblue you,please take some time look for my questions,i used cordova-2.0.0.js,but when i taked photos,my app progrom will exit,my logcat is:
    https://groups.google.com/forum/#!topic/phonegap-take-picture-error/-Foi6_rOqoM
    Thank you !!!

    ReplyDelete
  86. @Yuguang Zhao

    There is nothing in your logcat that indicates a crash.

    ReplyDelete
  87. When my program crash and then restart eclipse logcat will appear this a hint
    Could not find method android.webkit.WebView., referenced from method org.apache.cordova.CordovaWebView.

    ReplyDelete
  88. @Yuguang Zhao

    I'm looking for a stack trace.

    ReplyDelete
  89. Hi Simon,

    I'm trying to make camera work on s3, every time i click the save button after capturing the image the app crashes.
    This is the code i'm using .

    navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 20,
    sourceType: navigator.camera.PictureSourceType.CAMERA,
    mediaType: navigator.camera.MediaType.PICTURE,
    destinationType: Camera.DestinationType.FILE_URI,
    targetHeight:1024});
    I'm using phonegap 1.9.0.

    Please help me

    Thanks!

    ReplyDelete
  90. @shruti nair

    First, check "adb logcat" to see if you are getting an out of memory exception. If that is the case you may need to upgrade to 2.4.0 as the camera on the S3 is very good and creates very large images.

    ReplyDelete
  91. @Oliver Krylow

    Yes, it looks like there was an issue in 2.3.0. It should be resolved in the upcoming 2.4.0.

    ReplyDelete
  92. No we are not getting any out of memory exception but can we use any lower cordova version to solve this issue. We have found a solution for that, if we fix the orientation of the application to Landscape mode, the Camera will work in all devices however, our app is only required portrait orientation. Is there a way to fix the orientation on a specific page so we can open camera on landscape orientation and will use the app in portrait on other pages?

    Thanks

    ReplyDelete
  93. @shruti nair

    If your app is crashing then there is definitely a stack trace. What do you see from the stack trace?

    ReplyDelete
  94. Hi Simon
    Thanks for this post.
    Not sure whether you are still looking into this.

    I am stuck with this problem for 1 week. I have tried so many things like using different versions of cordova(2.1, 2.5, 2.7, etc.) and some of the configurations like keeping:
    quality: 100
    Leaving targetWidth, targetHeight so that default values will be taken etc.

    The issue is that once I take picture and while returning to the app, it crashes. This is happening only in some phones(Samsung Galaxy ACE, Micromax A87).

    The following is the stacktrace:

    05-19 18:21:10.449: W/dalvikvm(9945): threadid=1: thread exiting with uncaught exception (group=0x40142560)
    05-19 18:21:10.459: E/AndroidRuntime(9945): FATAL EXCEPTION: main
    05-19 18:21:10.459: E/AndroidRuntime(9945): java.lang.RuntimeException: Unable to resume activity {com.eiris/com.eiris.InAppTest}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=33, result=-1, data=Intent { (has extras) }} to activity {com.eiris/com.eiris.InAppTest}: java.lang.NullPointerException
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2120)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.os.Handler.dispatchMessage(Handler.java:99)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.os.Looper.loop(Looper.java:130)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.main(ActivityThread.java:3683)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at java.lang.reflect.Method.invokeNative(Native Method)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at java.lang.reflect.Method.invoke(Method.java:507)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at dalvik.system.NativeStart.main(Native Method)
    05-19 18:21:10.459: E/AndroidRuntime(9945): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=33, result=-1, data=Intent { (has extras) }} to activity {com.eiris/com.eiris.InAppTest}: java.lang.NullPointerException
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2107)
    05-19 18:21:10.459: E/AndroidRuntime(9945): ... 12 more
    05-19 18:21:10.459: E/AndroidRuntime(9945): Caused by: java.lang.NullPointerException
    05-19 18:21:10.459: E/AndroidRuntime(9945): at org.apache.cordova.DroidGap.onActivityResult(DroidGap.java:849)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.Activity.dispatchActivityResult(Activity.java:3908)
    05-19 18:21:10.459: E/AndroidRuntime(9945): at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
    05-19 18:21:10.459: E/AndroidRuntime(9945): ... 13 more

    ReplyDelete
  95. @ranjjose

    The stack trace helps but I need to know what version of PhoneGap you are using when you reproduce this issue. Then I can line up the NPE with the line in DroidGap that causes it.

    ReplyDelete
  96. @Simon:
    To follow up,
    phonegap 2.7.0 also crashed (same stack-trace). With 2.1.0, however, the app was re-starting while coming back to the app after taking a photo.
    Anyway, I could finally get it working by using foreground camera plugin(https://code.google.com/p/foreground-camera-plugin/). Thanks to them. Ref: https://groups.google.com/forum/?fromgroups#!topic/phonegap/S6bu5CSM5mQ

    ReplyDelete
  97. Hey Simon I still have this problem can u plz help me

    ReplyDelete
  98. @Patchara Lertudomtana

    Well I've done the best I can to have this issue happen less frequently but there is no way to completely remove it. What are you seeing?

    ReplyDelete
  99. Hi Simon,

    I'm having memory issues with Android 2.3 devices, with PhoneGap 2.8

    The error is:

    java.lang.RuntimeException: Unable to resume activity {com.dansmart.geosight/com.dansmart.geosight.Geosight}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.dansmart.geosight/com.dansmart.geosight.Geosight}: java.lang.NullPointerException
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=34, result=-1, data=null} to activity {com.dansmart.geosight/com.dansmart.geosight.Geosight}: java.lang.NullPointerException
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
    ... 12 more
    Caused by: java.lang.NullPointerException
    at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:866)
    at android.app.Activity.dispatchActivityResult(Activity.java:3908)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
    ... 13 more

    This error appears after having taken a photo when you click the ‘Save/ok’ button to accept the picture before resuming with the app. I have 7 reports of this error, 6 of which are this week, so it's happening regularly now with PhoneGap 2.8 whereas it wasn't happening with our previous release which was 2.1.

    We're using 100%, JPEG, FILE_URI, and no correction of orientation, as suggested. We also have android:configChanges="orientation|keyboard"

    Any ideas? Would upgrading to 3.0 help?

    Best regards,

    Dan

    ReplyDelete
  100. @Dan Smart

    Upgrading to 3.0.0 probably won't help. The Camera Intent has been problematic in PhoneGap Android since day one and only gets worse as Camera HW gets better.

    For config changes change it to:

    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"

    and give it a try.

    ReplyDelete
  101. Thanks Simon - the strange thing is that the issue is being reported on older devices (Android 2.3), so it shouldn't be due to camera HW.

    I've sent a release out with the update config, and I'll feedback if we get an improvement.

    Dan

    ReplyDelete
  102. Could Cordova not access the camera directly rather than using the camera activity?

    http://developer.android.com/reference/android/hardware/Camera.html

    Also, with html5 coming along, could cordova use the html5 media capture APIs instead?

    http://www.w3.org/TR/html-media-capture/

    In my case, I got the application to stop crashing by reducing the target image size to quite a low resolution (1024x768 or something) and also upgrading the the next gen phone, so the issue went away, but we still have some bugzilla's open to consider either direct hardware access, or using html5 media to replace the cordova camera API.

    ReplyDelete
  103. @Austin

    Yes, we could implement our own camera functionality but we are not in the business of writing a Camera app. Personally I wouldn't want to maintain something like that. You can use the ForegroundCamera plugin which provides a simple UI for taking pictures without using an intent.

    Well, we've already implemented an earlier version of the media capture API but it again uses intents. Personally I can't wait until the browser/web view natively implements more of the HTML5 API's as then PhoneGap can go away. Remember all of us PhoneGap devs are looking forward to the day where PhoneGap is no longer needed for folks to write HTML5/JS apps and get access to the device API's.

    ReplyDelete
  104. @donantidees

    I wish I had a solution for you. What is happening here and has been a problem for quite awhile is that Android is clearing out your application from memory. Then when the Intent to select a picture is done there is no app to return the value to. We've been banging our heads against this for awhile but we've got no solution as of yet.

    ReplyDelete
  105. @donantidees

    Other than pulling in the foreground camera plugin into the code no.

    ReplyDelete
  106. Hi Simon,
    Thank you for this great post! I hope you can help me with pictureSourceType. It working perfectly, but I want to know; if I want the photo taken to be saved in gallery as well as local server, which sourcetype should I use? And I wish you write a tutorial on phonegap+picture+localserver+database+android.

    I really appreciate your help and intelligent :)

    ReplyDelete
  107. @TrialAndError

    If you want the picture saved in the gallery you set the "saveToPhotoAlbum" option to "true". To save it on a server you'll need to use the FileTransfer.upload method.

    ReplyDelete
  108. Hi Simon, I'm using phonegap 2.8.0 and I have some problems when user take a picture from photolibrary.

    When user select an image sometimes app crash.

    I use this code:

    navigator.camera.getPicture(seleccionada2, noseleccionada2, {
    sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
    quality: 100,
    destinationType: Camera.DestinationType.DATA_URI,
    allowEdit: true,
    encodingType: Camera.EncodingType.PNG
    });

    The error is:

    java.lang.RuntimeException: Unable to resume activity {com.perfilempleo.perfil/com.perfilempleo.perfil.Perfilempleo}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=18, result=-1, data=Intent { dat=content://media/external/images/media/3186 }} to activity {com.perfilempleo.perfil/com.perfilempleo.perfil.Perfilempleo}: java.lang.NullPointerException
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2141)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2156)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1680)
    at android.app.ActivityThread.access$1500(ActivityThread.java:121)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3701)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=18, result=-1, data=Intent { dat=content://media/external/images/media/3186 }} to activity {com.perfilempleo.perfil/com.perfilempleo.perfil.Perfilempleo}: java.lang.NullPointerException
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2553)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2128)
    ... 12 more
    Caused by: java.lang.NullPointerException
    at org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:866)
    at android.app.Activity.dispatchActivityResult(Activity.java:3908)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:2549)
    ... 13 more

    Thanks in advance

    ReplyDelete
  109. Hi simon, Foreground Gallery Plugin is valid for phonegap 2.8.0?

    Thanks in advance

    ReplyDelete
  110. @marcos cuesta

    Using DATA_URL instead of FILE_URI is a sure way to kill your app. You are either going to run out of memory and crash the app or have the calling app get cleared out to save memory.

    ReplyDelete
  111. @Alejo Miguel Hernández García

    I'm not sure as I did not write it but it should be easy to upgrade if required. Probably just needs a few changes to the Java code to find the right classes.

    ReplyDelete
  112. @donantidees

    If I could make people do things, I'd be a much richer man than I am now :)

    Seriously though, it shouldn't be too hard to convert it to 3.0.0. Take a shot at it yourself and let me know if you need help.

    ReplyDelete
  113. hi simon

    i have problem at camera when i use cordova 3.5 and capture pic from camera the image getting rotate 90 degree at left side

    This is happen only at samsung note 2 and samsung grand at rest devices its working properly.

    Thanx in advance

    ReplyDelete
  114. @Daljeet Singh

    Are you using the "correctOrientation" parameter in your call to getPicture?

    IIRC sometimes Samsung puts their own bloatware camera on their devices and it is not coded as well as Google's camera.

    ReplyDelete