bad bitmap error when setting Uri - android

I would like to make an ImageView display an image on a website. So I create a new ImageView and execute imgView.setImageURI(uri);
When I launch the app the image does not appear and I get the error, "resolveUri failed on bad Bitmap Uri (uri)".
Any ideas on how to solve this?

If it's not a content URI, this link may help. It seems to indicate that imgView.setImageURI() should not be used for regular URIs. Copying in the relevant bit:
Yes, ImageView.setImageURI(ContentURI uri) works, but it is for content URIs particular to the Android platform, not URIs specifying Internet resources. The convention is applied to binary objects (images, for example) which cannot be exposed directly through a ContentProvider's Cursor methods. Instead, a String reference is used to reference a distinct content URI, which can be resolved by a separate query against the content provider. The setImageURI method is simply a wrapper to perform those steps for you.
I have tested this usage of setImageView, and it does work as expected. For your usage, though, I'd look at BitmapFactory.decodeStream() and URL.openStream().
Also to make this answer self-contained, the sample code from another post at that link, showing how to do it:
private Bitmap getImageBitmap(String url) {
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e(TAG, "Error getting bitmap", e);
}
return bm;
}
I haven't tested this code, I'm just paranoid and like to ensure SO answers are useful even if every other site on the net disappears :-)

Glide is an awesome library for displaying images!
Glide.with(context)
.load(uri)
.into(imageView);

You need to download the image and then set it as bitmap.
Here is one of the many examples:
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

Use library Picasso
Manifest
uses-permission android:name="android.permission.INTERNET"
build gradle
implementation 'com.squareup.picasso:picasso:2.71828'
Activity:
Picasso.get().load(photoUrl).into(imageView);

First, you should download the image and save it in your device(sdcard or memory).
Then, get its file path, using Uri.parse(filePath) to convert path to uri
finally, call ImageView's setImageURI(Uri) to fullfill.
-- I use this way to achieve my purpose and there is a bug:if the image is to large(maybe exceed 1Mb or so, it may report outOfMemeroy Exception!!!)

Related

Using uri (android.net.uri) as a link to get image from internet and put it in a ImageView

I have a item object, containing a Uri variable called image. something like this
http://icons.iconarchive.com/icons/designcontest/vintage/256/Type-icon.png
I tried to get from the class method the Uri and use it for setting up the ImageView called Image in my viewholder
viewHolder.Image.setImageURI(item.getImage());
but it didn't work, so I tried something more complex without success
//Image
URL url = null;
try {
url = new URL(item.getImage().toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
Bitmap bmp = null;
try {
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
viewHolder.Image.setImageBitmap(bmp);
} catch (IOException e) {
e.printStackTrace();
}
I have allowed internet permissions, and if I use some images from local with Uri.parse it works without any problem.
Here's the error I get from logcat
E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.net.URLConnection java.net.URL.openConnection()' on a null object reference
I think the problem is something in the url definiton but I'll ask you if someone had my same problem and how you solved. Thanks in advance!
for this purpose try to use a specific image library like Picasso, Glide or Fresco. The first one is the simplest with nice fluent interface and it loads images pretty fast:
Please check it, as you may don't know it. Here is a short description taken from its official site (link below):
Images add much-needed context and visual flair to Android
applications. Picasso allows for hassle-free image loading in your
application—often in one line of code!
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
Many common pitfalls of image loading on Android are handled
automatically by Picasso:
Handling ImageView recycling and download cancelation in an adapter.
Complex image transformations with minimal memory use.
Automatic memory and disk caching.
From: http://square.github.io/picasso/
As it already Open Source project you can check the code to improve it or make your own version fitted to your actual needs.
Hope it help
In all likelihood, url = new URL(item.getImage().toString()); is throwing a MalformedURLException, which your catch block is suppressing. As a result, url is null, which is why you're getting a NullPointerException. A constructor can't return a null, so this is the only thing I can imagine.
Unless you really know what you're doing, I recommend you use a library like Glide to do image fetching.

Corrupted Images From BitmapFactory

Once in a while when I am downloading images, some of them will appear with gray lines as displayed in the sample image below:
This tends to happen exclusively on poor network conditions.
My code for decoding images is essentially a modded version of that from UIL:
Bitmap decodedBitmap = BitmapFactory.decodeStream(stream, null, decodingOptions);
where stream is just an InputStream to the remote file
Now I've seen this behaviour on the Google Play Music app which makes me wonder if it's an issue with the BitmapFactory.
The only solution I've come up with so far is maybe doing a checksum comparison to make sure the entire image was downloaded.
Edit:
HttpURLConnection conn = getConnection(path);
InputStream inputStream = conn.getInputStream()
stream = new ContentLengthInputStream(new BufferedInputStream(download, BUFFER_SIZE), conn.getContentLength())
Solved it by using the following steps:
Open an InputStream to the image as normal
Write the stream to a ByteArrayOutputStream
Compare the length of the ByteArrayOutputStream to the Content-Length header from the HttpURLConnection
If mismatch then you've lost data in transit
Otherwise you can convert your ByteArrayOutputStream to a ByteArrayInputStream and use with the BitmapFactory as you see fit

save and laod image using universal image loader

Updated
So as suggested earlier, i used Universal image loader. But i am getting some error.
**This is the first time i am playing around with this kind of stuff.
Below are my codes :
Here is the code to save bitmap to internal storage using async:
Uri uri = Crop.getOutput(result);
try {
bmp = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
finally {
new saveDpToDisk().execute(bmp);
}
class saveDpToDisk extends AsyncTask{
#Override
protected Object doInBackground(Object[] params) {
try {
fos = openFileOutput("ProPic", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
return bmp;
}
}
and here is code to load image from storage using UIL:
#Override
protected Object doInBackground(Object[] params) {
FileInputStream fis;
try {
fis = openFileInput("ProPic");
String uri = String.valueOf(fis);
DisplayImageOptions options = new DisplayImageOptions.Builder().cacheOnDisk(true).build();
ImageLoader loader = ImageLoader.getInstance();
loader.displayImage(uri, pro_pic, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return pro_pic;
}
}
And this is the error I am getting (app doesnt force close, error just appears in logcat
UIL doesn't support scheme(protocol) by default [java.io.FileInputStream#42987180]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))
java.lang.UnsupportedOperationException: UIL doesn't support scheme(protocol) by default [java.io.FileInputStream#42987180]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))
at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromOtherSource(BaseImageDownloader.java:235)
at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:97)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.downloadImage(LoadAndDisplayImageTask.java:290)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryCacheImageOnDisk(LoadAndDisplayImageTask.java:273)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:229)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:135)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
________x_____________________x___________________________x_______________________
Original Question
My app has to load only one image (which user can select from gallery to set as his dp for that app).
So, What I did is I saved the selected pic to storage using FileOutputStream and then load the pic using FileInputStream in activity's onResume method.
But, what happens is that when the selected pic is too large, the app starts up too slowly (takes time to inflate view) and logcat shows memory heap of 30-60 MB.
So, i thought of storing the image in cache and load but dont exactly find a way to do so.
Shall i use picasso? If yes, how to use it for saving and laoding from cache.
Or are there any other ways to achieve what i need?
If you read this post on G+ by Koush you will get clear solutions for your confusions, I have put the summery of that, in that Android-Universal-Image-Loader is the winner for your requirement!
Picasso has the nicest image API if you are using network!
UrlImageViewHelper + AndroidAsync is the fastest. Playing with these
other two great libraries have really highlighted that the image API
is quite dated, however.
Volley is slick; I really enjoy their pluggable backend transports,
and may end up dropping AndroidAsync in there. The request priority
and cancellation management is great(if you are using network)
Android-Universal-Image-Loader is the most popular one out there
currently. Highly customizable.
This project aims to provide a reusable instrument for asynchronous
image loading, caching and displaying. It is originally based on Fedor
Vlasov's project and has been vastly refactored and improved since
then.
Considering all this Android-Universal-Image-Loader suites your requirement (Loading the images are on disk locally)!

Best way to download images from XML content

I am designing an Android application which will be displaying some news that will be retrieved from a remote URL in xml format, say http://adomain/latest.xml
The XML file has the following format:
<articles>
<article>
<id>6</id>
<title>A sample title</title>
<image>http://adomain/images/anImage.jpg</image>
<lastupdate>1326938231</lastupdate>
<content><![CDATA[Sample content]]></content>
</article>
...
</articles>
I have created an Updater Service which listens to Connectivity Changes and when the system has a connection over the internet, it tries to download the xml file. Then parse it and save data. The Updater runs on a separate thread, every 10 minutes.
My question is:
What is the best way to handle the images?
a) Should I perform lazy loading on images when a news item is displayed
OR
b) Should I download the image when I parse the xml file?
I recommend lazy loading as the news item is displayed, so you don't use excessive bandwidth (and potentially cost for the user). No point in downloading images if the user never wants to look at them.
for images, I think you always follow lazy loading because, image loading may take some time, and also an efficient lazy loader can help you to avoid any future memory issue.
Just fetch <Image> tag data from your XMl.
String imgURL = your <Image> value;
ImageView imageView = new ImageView(this);
Bitmap bmp = BitmapFactory.decodeStream(new java.net.URL(imgURL).openStream());
imageView.setId(i);
imageView.setImageBitmap(bmp);
This will work to set image and you also get image in "bmp".
Android provide directly show image from URL:
For Store Image to Sd Card:
File file = new File (pathOfSdCard, iamgeName);
try {
file.createNewFile();
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Put Line to your AndroidMenifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
This all i using in my app. it works fine.
I hope this will helps you a lot.

How to use Android's CacheManager?

I'm currently developing an Android application that fetches images using http requests. It would be quite swell if I could cache those images in order to improve to performance and bandwidth use.
I came across the CacheManager class in the Android reference, but I don't really know how to use it, or what it really does.
I already scoped through this example, but I need some help understanding it:
/core/java/android/webkit/gears/ApacheHttpRequestAndroid.java
Also, the reference states:
"Network requests are provided to this component and if they can not be resolved by the cache, the HTTP headers are attached, as appropriate, to the request for revalidation of content."
I'm not sure what this means or how it would work for me, since CacheManager's getCacheFile accepts only a String URL and a Map containing the headers. Not sure what the attachment mentioned means.
An explanation or a simple code example would really do my day. Thanks!
Update
Here's what I have right now. I am clearly doing it wrong, just don't know where.
public static Bitmap getRemoteImage(String imageUrl) {
URL aURL = null;
URLConnection conn = null;
Bitmap bmp = null;
CacheResult cache_result = CacheManager.getCacheFile(imageUrl, new HashMap());
if (cache_result == null) {
try {
aURL = new URL(imageUrl);
conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
cache_result = new CacheManager.CacheResult();
copyStream(is, cache_result.getOutputStream());
CacheManager.saveCacheFile(imageUrl, cache_result);
} catch (Exception e) {
return null;
}
}
bmp = BitmapFactory.decodeStream(cache_result.getInputStream());
return bmp;
}
I don't think the CacheManger can be used outside of a WebView as noted in this bug report
http://code.google.com/p/android/issues/detail?id=7222
I came across this issue awhile ago as well. The cache manager is only for the webview and not really useful outside of that. For my application I needed to cache xml responses and images so I ended up writing my own cache manager to accomplish that. Nothing too terrible but certainly not as easy as using a would-be built-in one.
If you have any questions about the specifics, add a comment to my post, I check back frequently.

Categories

Resources