Android : Bitmap : From parcel : Out of memorry exception - android

I am using a bundle to send a bitmap from one application to another.
And i retrieve the bitmap from the bundle for use in a different application.
The specific use of bundle was necessary in this place.
And when i read it out i get a OUT OF MEMORY EXCEPTION.
bitmap = (Bitmap)receivedmsg.getData().getParcelable("myobject");
Any suggestions ?

It means what it says. The image you serialized is too big to be read back into memory in the other app. The fastest fix is what M Mohsin Naeem alludes to: you need to make the image smaller! Do so in the app that sends the image. For example, if that app is reading from a file, you can set it to down-sample the image to a smaller size.
Also consider whether you really need to send the image this way, or whether you could save it to the SD card, and then process it without reading into memory.

Related

Which is the better way to pass Image between 2 activities? Saving to file or Caching?

I know this is a very frequently asked questions and there are multiple answers. My question is "which is better?"
I've an activity where I capture an image using camera. I need to pass this image to another activity.
One way is to create Bitmap and pass it in putExtra since Bitmap is a Parcelable. This fails when the image size is too big.
I found 2 solutions. This answer uses MemoryCache to save and retrieve the image. Many answers (this, this and this) recommend to save the image to storage and then pass the path to new activity and read the image there.
Which is a better method in this case? (In terms of speed and memory)
It is safer in any case work with path or link than pass it as it is. It works not only with images but with most types of data. At the same time while working with path you can easy make if/else checks and handling some unexpected scenarios. Also pass the path is much faster.

Is there anyway to pass Image data through an intent?

I know how to do this converting it to a bitmap, but I want an Image (android.media) on the receiver side.
Thanks in advance.
If you want to pass only one bitmap at a time, I suggest creating a static variable in a class. and assign the bitmap object to it, and use it in the receiver class.
But if this is very big bitmap, it may cause OutOfMemory issue.
You probably don't want to do this. Even if you create a Serializable or Parcelable object that includes your data like this:
http://www.javacodegeeks.com/2014/01/android-tutorial-two-methods-of-passing-object-by-intent-serializableparcelable.html
which you may be able to do, by creatively encoding your image.
But an Intent has a limitation in size. See this post here:
Maximum length of Intent putExtra method? (Force close)
It says 1MB, but in my experience it might be as high as 4MB, depending on the platform (I may have that wrong, I don't have a specific reference to Android documentation to support it, but I see errors that appear to support it).
I'm sure you can move a lot of images within this restriction, but for any that fall outside of it, you will need a "work around" - which you should then probably make the "standard" and avoid the issue altogether.

startActivity(intent) not working in Google glass

I am developing an app for Google glass using using a Immersion Pattern.
I am using start activity to switch between different tiles using below code.
Intent showImageDetails = new Intent(MainActivity.this, CapturedImageActivity.class);
showImageDetails.putExtra("IMAGE_DATA", data);
startActivity(showImageDetails);
data variable holds byte array for captured image.
Few time device is not able to start the activity and it exits the application and goes back to OK Glass tile.
Have anyone observed this issue?
I have used charades as an example which comes with API example.
Based on your comment, my wild guess is your image is too big to be sent with intent. Have you noticed the JAVA BINDER FAILURE error in the log or TransactionTooLargeException:
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
Also see Passing data of a non-primitive type between activities in android:
What you do not want to do is pass big stuff via extras. For example, if you are creating an application that grabs pictures off the camera, you do not want to pass those in extras -- use a static data member (icky as that sounds). Intents are designed to work cross-process, which means there is some amount of data copying that goes on, which you want to avoid when it is not necessary for big stuff.
I think if your image is large, it is better to pass the URI or ResourceID of the image but not the image itself. Hope this helps.

Get image uri from picasso?

I have a fairly large list of image URL's that I'm using to load up a ViewPager using Picasso. I need to be able to provide sharing capabilities for these images via an intent (ultimately sharing via ShareActionProvider). From what I've read, Picasso isn't really built to handle this sort of thing out of the box, though it provides all the necessary tools to do so.
My plan before research was to create a simple LruCache which uses the url as the key and bitmap value. This caching would occur in onBitmapLoaded via Picasso's Target interface. Whenever I want to share an image, I'll check the cache for the bitmap. If it's not there, I'll fetch with Picasso. Now that I have a cached bitmap regardless, I'll write to a file (...this part doesn't seem right, though I have to write to a file to get a uri, right?) and add the file uri to the intent.
However I see that with the Picasso.Builder I can set (and retain a reference to) my own cache - https://stackoverflow.com/a/18552559/413254. This means I could do away with the custom Target and confusion with properly implementing hashCode and equals methods to ensure accurate recycling, retrieval, etc.
My question is, how does Picasso use this cache? What are the keys? Is there a way to get a bitmap Uri without writing it to disk?
If you want to use ShareActionProvider to share the image on the current page you don't have to keep your own cache of images. But to be able to share it to others, the image should be in the shared file system on the device.
It would be better if you use image loading libraries with custom disk cache support like Universal Image Loader
If you want to use Picasso (which is a good decision).
You either have to save a copy of the image on every page change which is nor a good option.
Or you can give a custom network handler to Picasso and set a custom cache implementation to it. I would suggest using OkHttp with custom caching which stores files in the format you desire. When you do that, you have to have a function that converts image URLs to file path on a device.
In every page change, if you have a Fragment inside your ViewPager, put the ShareActionProvider into your Fragments.
Get the reference of the ShareActionProvider inside onCreateOptionsMenu. And then set the Intent with the file path you get.
Intent shareIntent = new Intent(Intent.ACTION_SEND);
Uri phototUri = Uri.parse(Utils.getFilePath(imageUrl));
shareIntent.setData(phototUri);
shareIntent.setType("image/png");
shareIntent.putExtra(Intent.EXTRA_STREAM, phototUri);
mShareActionProvider.setShareIntent(intent);
Edit:
The other option I would prefer is to ditch ShareActionProvider and use a normal menu item for this. The problem with ShareActionProvideris that you have to make the share Intent ready for user to share before hand. You have to make it ready even the user won't share it.
But when you have a normal button, it is much easier because you only make the operation when the user clicks the share button. In that case you can simply request the image one more time from Picasso with a Target object and write the Bitmap you got to a file in the shared external file system and share it.

How long data can pass through intent in android

I want to know how long data can pass though intent. If i am passing parcelabel(as i am passing bitmap) more than 500x500 size it is give java transection binding fail.
If it's small (thumbnail) then it should be fine, if it is big you can end up with failed binder transaction errors. To avoid it you should pass a URI to location where it is saved. You can put it on sdcard if you have permission or in cache folder if not. If you are sending intent to some other process, then you should put bitmap on sdcard to make it readable by other processes. Last solution is to write Content Provider, this is usefull when you are sharing bitmap files, and want to for example attach bitmap with email.

Categories

Resources