All was perfect before I realize that some of my images doesn't load because of HTTP code 302 - moved temporary or "The data requested actually resides under a different URL". So this means my request is redirected with "Location" header. I found that Android do not support any redirect following - with RedirectHandler or anything else (in SDK v2.3).
I solved my problem with simply reading headers, finding Location header and recursively call downloading method again. Warning: This technique does not prevent circular redirects, so you have to check for them on your own. Here is my method:
private static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client =
AndroidHttpClient.newInstance("Android");
final HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
final int statusCode =
response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Header[] headers = response.getHeaders("Location");
if (headers != null && headers.length != 0) {
String newUrl =
headers[headers.length - 1].getValue();
// call again with new URL
return downloadBitmap(newUrl);
} else {
return null;
}
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
// do your work here
return BitmapFactory.decodeStream(inputStream);
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
request.abort();
} finally {
if (client != null) {
client.close();
}
}
return null;
}
Lets all hope Google engineers will fix following redirects in future versions of Android SDK
Edit
I have found that you shouldn't use AndroidHttpClient but instead use HttpUrlConnection. This class follows up to 5 redirects and supports cache. Here is the improved code snippet:private static Bitmap downloadBitmap(String stringUrl) {
URL url = null;
HttpURLConnection connection = null;
InputStream inputStream = null;
try {
url = new URL(stringUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(true);
inputStream = connection.getInputStream();
return BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
} catch (Exception e) {
Log.w(TAG, "Error while retrieving bitmap from " + stringUrl, e);
} finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}