PhoneGap: Application crash taking portrait picture - android

I am using jQuery Mobile and PhoneGap to create an app that allows users to take a picture, view it on screen, and then upload it to a server application that will ultimately post it on a website.
This works well if I take the photo in Landscape mode, but crashes the application when I take a Portrait photo. As you can see from the code snippet below I am using the correctOrientation parameter to attempt to orient the photo after it is taken. Without this parameter the application doesn't crash, however the photo is in the wrong orientation when it gets displayed.
Right now I'm testing this on Sony XPERIA android phone.
Here is the code responsible for the work.
function onPhotoFail(message) {
alert('Failed because: ' + message);
}
function onPhotoSuccess(imageURI) {
var $image = $("img#upload-image");
$image.attr("src", imageURI);
}
function capturePhoto() {
navigator.camera.getPicture(onPhotoSuccess, onPhotoFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI , correctOrientation: true });
}
Here's the stack trace:
E/AndroidRuntime(31760): FATAL EXCEPTION: main
E/AndroidRuntime(31760): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
E/AndroidRuntime(31760): at android.graphics.Bitmap.nativeCreate(Native Method)
E/AndroidRuntime(31760): at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
E/AndroidRuntime(31760): at android.graphics.Bitmap.createBitmap(Bitmap.java:444)
E/AndroidRuntime(31760): at org.apache.cordova.CameraLauncher.getRotatedBitmap(CameraLauncher.java:483)
E/AndroidRuntime(31760): at org.apache.cordova.CameraLauncher.onActivityResult(CameraLauncher.java:326)
E/AndroidRuntime(31760): at org.apache.cordova.DroidGap.onActivityResult(DroidGap.java:823)
E/AndroidRuntime(31760): at android.app.Activity.dispatchActivityResult(Activity.java:3908)
E/AndroidRuntime(31760): at android.app.ActivityThread.deliverResults(ActivityThread.java:2549)
E/AndroidRuntime(31760): at android.app.ActivityThread.handleSendResult(ActivityThread.java:2595)
E/AndroidRuntime(31760): at android.app.ActivityThread.access$2000(ActivityThread.java:121)
E/AndroidRuntime(31760): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:973)
E/AndroidRuntime(31760): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(31760): at android.os.Looper.loop(Looper.java:130)
E/AndroidRuntime(31760): at android.app.ActivityThread.main(ActivityThread.java:3701)
E/AndroidRuntime(31760): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(31760): at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime(31760): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
E/AndroidRuntime(31760): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
E/AndroidRuntime(31760): at dalvik.system.NativeStart.main(Native Method)
I've done some searching around, and I don't see anybody having this exact problem. Any help is appreciated

I would have to see your stack trace to be sure but it is probably an OutOfMemoryException. Android handles image manipulation very badly. It basically needs to load the entire image into memory where each pixel is 4 bytes, that means up to 40 megabytes for a lot of modern phone cameras.
My only suggestion right now is to try to switch the quality to 100. I know it sounds counter-intuitive but it make keep there from being as much processing in the background.
You can read my blog post talking about some of the problems with the Camera:
http://simonmacdonald.blogspot.ca/2012/07/change-to-camera-code-in-phonegap-190.html
Also, if I can see the stack trace it would help.

this thread might be a little old but the issue is still out there. I've been looking more deeply into the phonegap plugins code and noticed that the problem is, as Simon said, with Android class not handling the image operations -> loading a big bitmap via Bitmapfactory.decodeStream method. However, if you dont need to resize the image (while taking it from gallery -> you can do it later, on serverside for example) and you want to preserve the 100 quality AND you don't need to use correctOrientation option AND your destination type is FILE_URI.. simply, you just need the images URI to upload it somewhere, for example, then you need to include 3 options: targetWidth set to -1, targetHeight set to -1 and correctOrientation set to false:
navigator.camera.getPicture(cameraSuccess, cameraError, { quality: 100, targetWidth: -1,
targetHeight: -1, correctOrientation: false,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.SAVEDPHOTOALBUM});
You can find info on that in plugins code (comment on line 394, cordova 2.8.0). Dont know why its not in documentation though ;)

Related

Out of Memory Picasso Lib

I'm developing an app that loads a lot of images through lib Picasso. When I'm navigating through the app, suddenly the app crashes, giving out of memory.
I already tried to do somethings to avoid this kind of problem, but with no success.
If someone could help me, i would be glad.
Below the code:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.codal.whatsee/com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity}: android.view.InflateException: Binary
XML file line #55: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2217)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2266)
at android.app.ActivityThread.access$800(ActivityThread.java:145)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5141)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #55: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:343)
at android.app.Activity.setContentView(Activity.java:1929)
at com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity.onCreate(ItemPostFragmentActivity.java:150)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2171)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
... 23 more
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
at android.content.res.Resources.loadDrawable(Resources.java:2208)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at android.widget.ImageView.<init>(ImageView.java:129)
at android.widget.ImageView.<init>(ImageView.java:119)
at com.codal.whatsee.utils.SquareImageView.<init>(SquareImageView.java:13)
... 26 more
OBS: This problem happens not just in this class, but in any other class happens too.
This sounds a lot like your application is leaking memory and the image decoding is just the last operation that fills the heap. You should use the android DDMS tools and create a heap dump of your app after short use. If you see many Activities or Fragments in the dump, you should try to figure out which objects are still holding references to them.
Here is the related page from the developer site:
https://developer.android.com/tools/debugging/debugging-memory.html
You can expect such exception when dealing with images and bitmap. In present case it appears that out of memory is due to loading of a large/big image which consume the available memory and creating issue.
Luckily picasso lib offers an option to scale down your image so that it may not consumed much memory and thus lower down the chances for getting out of memory exception.
See if this below code is helpful to you or not.
Picasso.with(context).load(file).resize(sizeToScaleDown, sizeToSacleDown).onlyScaleDown().into(imageView);
Note: onlyScaleDown() function only works if you have also used resize() function. Using onlyScaleDown() function without resize() function will cause you exception.
Android 4.2 and 4.3 do not free the memory for a bitmap unless you finish the activity using the bitmap or recycle it (Bitmap.recycle()). See Android Bitmap Memory Analysis - Part 3. API Version Comparison for a detailed analysis. In Android 4.3 you need to additionally remove the image view from the view hierarchy.
So if you have an app where you can build up a deep navigation history and are using Picasso, you will run out of memory sooner or later because Picasso does not track references to bitmaps and therefore cannot call Bitmap.recycle() for them.
We had a similar issue and finally switched to Facebook's Fresco library, which goes at great length to track references. It is therefore more complex too use but it pays off.
You may be getting OOM because of the following:
You are doing some operation that continuously demands a lot of memory. Like Picasso Lib fetching large images/bitmaps which plays with bitmap operations
Picasso uses fit() or resize() methods while fetching the images. ReferenceLink
Memory leaks: You didn’t made the previous objects you allocated eligible for Garbage Collection (GC)
Use memory analyzer tool for taking Dump check where object are getting leak.
Dealing with large bitmaps. Scaling and bitmap operation take the memory from the heap.
I came across this link. It may help you : Link

Processing: FATAL EXCEPTION: Animation Thread java.lang.OutOfMemoryError (Android mode)

I am running an android app on my device using processing. But I get this error:
FATAL EXCEPTION: Animation Thread
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:592)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:691)
at processing.core.PApplet.loadImage(Unknown Source)
at processing.test.djtubedesktop.DJTubeDesktop.loadImages(DJTubeDesktop.java:972)
at processing.test.djtubedesktop.DJTubeDesktop.setup(DJTubeDesktop.java:62)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PGraphicsAndroid2D.requestDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
I have tried this:
1) Going to File -> preferences, and select "then Increase maximun available memory to" 10240 MB
2) Reducing the number of frames.
I have this 2 code lines:
images = loadImages("Animation_data/movie", ".jpg", 134);
recordPlayer = loadImages("black-record_", ".png", 36);
I have replaced 134 and 36 for 50 and 10, and by doing this I dont get the error, but it still does not work
The programs runs perfectly on java
I need to run it on my android device
The image you are manipulating is too large for Android. You are running out of Bitmap memory Try making the image smaller. You might want to check this link.
OutOfmemory Exception :-
this is because the image size is heavy.try using this code.
Bitmap bitmapimagesize = Bitmap.createScaledBitmap(your bitmap,
yourbitmap.getWidth() / 5, yourbitmap.getHeight() / 5,
false);
or this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
bitmap = BitmapFactory.decodeFile(image_path, options);

Out of Memory Error while loading bitmaps

i have an android app with 3 acitivtys:
A1 --starts--> A2 --starts--> A3 --when finished his process: starts--> A1
(so i don't "finish();" an app. i start the next activitys with "startActivity(..);" the whole time after userinteraction)
so there is a loop in these 3 activitys.
On each Activity, i display 3-9 pictures, located on the SD-card, which i load with my following function:
try
{
Uri selectedImageURI = Uri.parse(strImagePath);
File imgFile = new File(getRealPathFromURI(selectedImageURI, c));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ivTmp.setImageBitmap(myBitmap);
}catch (Exception e)
{
return null;
}
This all works.
But sometimes (after looping a few times through my activitys), my app crashes..
Logcat tells me:
01-16 13:42:15.863: DEBUG/dalvikvm(23161): GC_BEFORE_OOM freed 10K, 9% free 59019K/64400K, paused 29ms, total 30ms
01-16 13:42:15.863: ERROR/dalvikvm-heap(23161): Out of memory on a 8018704-byte allocation.
01-16 13:42:15.863: ERROR/AndroidRuntime(23161): FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
at android.content.res.Resources.loadDrawable(Resources.java:1965)
at android.content.res.Resources.getDrawable(Resources.java:660)
at android.widget.ImageView.resolveUri(ImageView.java:616)
at android.widget.ImageView.setImageResource(ImageView.java:349)
at <MyApp>.MyActivity$6.run(MyActivity.java:143)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Someone can give my some tips how to handle the crashes?
Maybe its because my activitys are set to state "paused" instead of closing them correctly?
for quick fix you can add
android:largeHeap="true" in your manifest application tag
link here:
I face OOM problem for my table in kindle and nook
Heap size (large)
android:largeHeap="true"
there specification is mentioned to use larger heap link here:
edit: use Caching Bitmaps technique link here
I had the similar problem while displaying high resolution images. I have searched and applied all the android bitmap solutions given in http://developer.android.com/training/displaying-bitmaps/index.html and the following caches mekanism in the link. but none of them work. not any right solution anywhere. Then I figured out that the problem is : I couldnt use the drawable folder structure right. I was keeping high resolution images in mdpi and hdpi folders . this cause android scale up the images to the ultra sizes. 100 kb image was causing 20 mb increase in memory thanks to the android monitor / memory section.
so I have added these ultra resolution images to xxhdpi folder , then It was FIXED suddenly. then my image slider work flawlessly
Yeah android doesnt immediately destroy activities when they are not visible to the user, but there are a number of lifecycle methods that are called depending on the current state. Check out http://developer.android.com/guide/components/activities.html#Lifecycle
You could try finishing the activities in onStop() or onDestroy() as these will be called when the activity is not visible and when the system runs low on memory respectively. :-)
This is due to the high resolution of image you have to scaling the bitmap use the following code
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
int h = 100; // height in pixels
int w = 100; // width in pixels
Bitmap photoBitMap = Bitmap.createScaledBitmap(myBitmap,h, w, true);
ivTmp.setImageBitmap(photoBitMap);

Application works on emulator, but not on real device - float type

My application works great while using the emulator, but it crashes while working on real device. I code it for Android 2.2. Real device is 2.3.6.
Problem is here:
When I use something like that:
tvPlayerOneScores.setText("-" + numberFormat.format(level));
it works great both on emulator and real device.
But when I try this:
tvPlayerOneScores.setText("-" + numberFormat.format(level * 0.5f));
it works on emulator, but crashes on real device.
Stack Trace:
java.lang.NumberFormatException
at org.apache.harmony.luni.util.FloatingPointParser.parseFltImpl(Native Method)
at org.apache.harmony.luni.util.FloatingPointParser.parseFloat(FloatingPointParser.java:321)
at java.lang.Float.parseFloat(Float.java:323)
at java.lang.Float.valueOf(Float.java:362)
at com.amrotek.truthordare.GameActivity$4.onClick(GameActivity.java:287)
at android.view.View.performClick(View.java:2552)
at android.view.View$PerformClick.run(View.java:9229)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
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)
EDIT:
I multiplied all values by 10, so I only work with integer numbers when I do arithmetic operations. At the end I just divide end value by 10. It works :)
you should have included faulty line in the question not in the comments:
playerOnePoints = Float.valueOf(numberFormat.format(playerOnePoints - level * 0.5f));
since it's not enough to make a conclusion, here's a short list of things for you to check:
why do you need to format a number with numberFormat just to convert it back with valueOf?
what's the numberFormat, does it really produce valid float strings?
is playerOnePoints float or Float? should not you use parseFloat() instead of valueOf()?
Finally, if you still are unable to solve your problem, I'd suggest to replace the aforementioned line with simple:
playerOnePoints = playerOnePoints - level * 0.5f;
That should do the trick =)
ps. also you migth want to get acquainted with Math.floor()/ceil(), if I understood your intentions with parseFloat()/numberFormat() correctly.

PlayN Android 2.3.x OutOfMemory

In our app we have a lot of images. When they needed we get them in
such way: PlayN.assets().getImage("imageURL");
In android 2.3 there is limit for 24mb of bitmap resources. So, while
showing images on Screen2(let's say Game) i must hide (unload) images
from Screen1(lets say Intro).
I have reference to image from Screen1 and i can call clear() method:
CanvaseImage referenceToImage - i need to unload,
referenceToImage.canvas().clear();
BUT, - this way do not unload image from android memory in 2.3.x -
( Android: Bitmap recycle() how does it work?...
this post tell that i should call recycle() on bitmap, since bitmaps
are stored in non-management memory and cant be shrinked from there by
GC.)
and i have such stackTrace for android if images from Screen1 are not
unloaded from memory:
06-11 09:16:45.197: E/AndroidRuntime(23621): FATAL EXCEPTION: GLThread
10
06-11 09:16:45.197: E/AndroidRuntime(23621):
java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap
Size=9479KB, Allocated=6032KB, Bitmap Size=23347KB)
06-11 09:16:45.197: E/AndroidRuntime(23621): at
android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
06-11 09:16:45.197: E/AndroidRuntime(23621): at
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:694)
06-11 09:16:45.197: E/AndroidRuntime(23621): at
playn.android.AndroidAssets.decodeBitmap(AndroidAssets.java:158)
06-11 09:16:45.197: E/AndroidRuntime(23621): at
playn.android.AndroidAssets.doGetImage(AndroidAssets.java:79)
06-11 09:16:45.197: E/AndroidRuntime(23621): at
playn.core.AbstractAssets.getImage(AbstractAssets.java:39)
Is there some way to call playN 's magic for recycling bitmaps in
Android 2.3.x memory model?
Have you already taken a look at the Google article about memory managment? They really give a fairly in depth explanation of how to deal with that bitmap issue.
why don't you use LruCache for caching bitmaps? see article here

Categories

Resources