views:

60

answers:

2

Hi all, I am working on an application that downloads images from a url. The problem is that only some images are being correctly downloaded and others are not. First off, here is the problem code:

public Bitmap downloadImage(String url) {
    HttpClient client = new DefaultHttpClient();
    HttpResponse response = null;
     try {
         response = client.execute(new HttpGet(url));
     } catch (ClientProtocolException cpe) {
        Log.i(LOG_FILE, "client protocol exception");
         return null;
     } catch (IOException ioe) {
            Log.i(LOG_FILE, "IOE downloading image");
            return null;
     } catch (Exception e) {
            Log.i(LOG_FILE, "Other exception downloading image");
            return null;
     }

     // Convert images from stream to bitmap object
     try {
         Bitmap image = BitmapFactory.decodeStream(response.getEntity().getContent());
         if(image==null)
             Log.i(LOG_FILE, "image conversion failed");
         return image;
     } catch (Exception e) {
         Log.i(LOG_FILE, "Other exception while converting image");
         return null;
     }
}

So what I have is a method that takes the url as a string argument and then downloads the image, converts the HttpResponse stream to a bitmap by means of the BitmapFactory.decodeStream method, and returns it. The problem is that when I am on a slow network connection (almost always 3G rather than Wi-Fi) some images are converted to null--not all of them, only some of them. Using a Wi-Fi connection works perfectly; all the images are downloaded and converted properly.

Does anyone know why this is happening? Or better, how can I fix this? How would I even go about testing to determine the problem? Any help is awesome; thank you!

+1  A: 

This is a known issue with the JPEG decoder. There are two solutions. Either you download the entire image in a byte[] array using a ByteInputStream and then decode the array (this is what I do in code.google.com/p/shelves.) Another solution is to create a wrapper InputStream as shown below:

public class PatchInputStream extends FilterInputStream {

  public PatchInputStream(InputStream in) {
    super(in);
  }

  public long skip(long n) throws IOException {
    long m = 0L;
    while (m < n) {
      long _m = in.skip(n-m);
      if (_m == 0L) break;
      m += _m;
    }
    return m;
  }

}
Romain Guy
what is m and what is n? I have some problems understanding the code sample maybe some longer variable names would help and maybe a comment or two. Also do you have a link to the bug request on this issue or is this is a general problem that can not be solved in a future version of the jpeg decoder?
Janusz
Thank you very much Romain Guy! I would have never figured this out without your help.For anyone else that comes across this, the first solution Romain Guy mentioned can be found in this class of his program: http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java
Mike