/*-
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.imageloader;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.CacheResponse;
import java.net.ContentHandler;
import java.net.URLConnection;
/**
* A {@link ContentHandler} that decodes a {@link Bitmap} from a
* {@link URLConnection}.
* <p>
* The implementation includes a work-around for <a
* href="http://code.google.com/p/android/issues/detail?id=6066">Issue 6066</a>.
* <p>
* An {@link IOException} is thrown if there is a decoding exception.
*/
public class BitmapContentHandler extends ContentHandler {
@Override
public Bitmap getContent(URLConnection connection) throws IOException {
InputStream input = null;
try {
input = connection.getInputStream();
input = new BlockingFilterInputStream(input);
return createBitmap(input);
} catch(NullPointerException e) {
// There is a bug with the implementation of caching requests in the HttpsURLConnectionImpl object
// I try to recover from it here using reflection
try {
Field httpsEngineField = connection.getClass().getDeclaredField("httpsEngine");
if(!httpsEngineField.isAccessible())
httpsEngineField.setAccessible(true);
Object httpsEngine = httpsEngineField.get(connection);
Field cacheResponse = httpsEngine.getClass().getSuperclass().getDeclaredField("cacheResponse");
if(!cacheResponse.isAccessible())
cacheResponse.setAccessible(true);
CacheResponse response = (CacheResponse) cacheResponse.get(httpsEngine);
InputStream input2 = response.getBody();
try {
return createBitmap(input2);
} finally {
input2.close();
}
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchFieldException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
} finally {
if(input != null)
input.close();
}
}
/**
* Actually creates the bitmap from the imput stream
* @param input
* @return the bitmap
* @throws IOException
*/
private Bitmap createBitmap(InputStream input) throws IOException {
Bitmap bitmap = BitmapFactory.decodeStream(input);
if (bitmap == null) {
throw new IOException("Image could not be decoded");
}
return bitmap;
}
}