I posted a question last night about this issue, but I dont think I explained it well enough to get the proper help. So basically, I have an application where you can press a button which will let you select an image from your gallery and show it in an ImageView I have displayed in the app. This all works great. However, when I press the button again and choose a different picture the app force closes.
UPDATE Now, if I take a photo from my downloads photo folder in the gallery it works fine, can switch photos as often as I like. But when I go back to my camera photo folder to change the picture it force closes.
UPDATE 2 It also works fine with any other folder I have in my Gallery app. Only one having this problem (force close) is on the "Camera" Folder
UPDATE 3 19660800-byte external allocation too large for this process. is causing the issue. Any ways on reducing the size of the photos being selected?
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
private ImageView img;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img = (ImageView)findViewById(R.id.myimageview);
((Button) findViewById(R.id.taptoadd))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
System.out.println("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
here is the log
11-23 16:33:15.871: D/dalvikvm(9171): GC_EXTERNAL_ALLOC freed 51K, 49% free 2793K/5447K, external 20868K/22916K, paused 50ms
11-23 16:33:15.878: E/dalvikvm-heap(9171): 19660800-byte external allocation too large for this process.
11-23 16:33:15.886: E/GraphicsJNI(9171): VM won't let us allocate 19660800 bytes
11-23 16:33:15.906: D/dalvikvm(9171): GC_FOR_MALLOC freed <1K, 49% free 2792K/5447K, external 1668K/20868K, paused 18ms
11-23 16:33:15.906: D/skia(9171): --- decoder->decode returned false
11-23 16:33:15.906: D/AndroidRuntime(9171): Shutting down VM
11-23 16:33:15.910: W/dalvikvm(9171): threadid=1: thread exiting with uncaught exception (group=0x40015560)
11-23 16:33:15.937: E/AndroidRuntime(9171): FATAL EXCEPTION: main
11-23 16:33:15.937: E/AndroidRuntime(9171): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.widget.ImageView.resolveUri(ImageView.java:521)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.widget.ImageView.setImageURI(ImageView.java:305)
11-23 16:33:15.937: E/AndroidRuntime(9171): at snapshot.app.LinearLayoutsActivity.onActivityResult(LinearLayoutsActivity.java:48)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.Activity.dispatchActivityResult(Activity.java:3908)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.deliverResults(ActivityThread.java:2528)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.access$2000(ActivityThread.java:117)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.os.Handler.dispatchMessage(Handler.java:99)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.os.Looper.loop(Looper.java:130)
11-23 16:33:15.937: E/AndroidRuntime(9171): at android.app.ActivityThread.main(ActivityThread.java:3683)
11-23 16:33:15.937: E/AndroidRuntime(9171): at java.lang.reflect.Method.invokeNative(Native Method)
11-23 16:33:15.937: E/AndroidRuntime(9171): at java.lang.reflect.Method.invoke(Method.java:507)
11-23 16:33:15.937: E/AndroidRuntime(9171): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-23 16:33:15.937: E/AndroidRuntime(9171): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-23 16:33:15.937: E/AndroidRuntime(9171): at dalvik.system.NativeStart.main(Native Method)
The error you are getting means that the bitmap you are loading is too big. You need to downsample it. See this question for some great examples on how to deal with this: Strange out of memory issue while loading an image to a Bitmap object
Update: Instead of telling the ImageView which URI to load as a Bitmap, you need to load the bitmap first yourself and then set that bitmap as the image on the ImageView. This is pretty straightforward.
To load a bitmap from you must first convert the URI to a String (I think you can use URI.getPath()
although I'm not sure) that contains the path to the image then you can load the bitmap with:
Bitmap b = BitmapFactory.decodeFile(pathToImage);
This will decode the entire bitmap, instead you want to downsample the bitmap to the desired resolution. Lets say your imageview will be 125x125 pixels and your image is 1000x1000 pixels. 125/1000 = 8
so we only need to decode every 8th pixel. To do this we do the following:
int inSample = 8;
opts = new BitmapFactory.Options();
opts.inSampleSize = inSample;
Bitmap b = BitmapFactory.decodeFile(pathToImage, opts); // this bitmap will be 1/8 the size of the original
Its pretty straight forward and should solve your memory issues. See the 2nd part of my answer to this question: Android GalleryView Recycling for a more extensive explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With