12bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch/* 22bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * Copyright (C) 2012 The Android Open Source Project 32bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 42bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * Licensed under the Apache License, Version 2.0 (the "License"); 52bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * you may not use this file except in compliance with the License. 62bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * You may obtain a copy of the License at 72bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 82bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * http://www.apache.org/licenses/LICENSE-2.0 92bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 102bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * Unless required by applicable law or agreed to in writing, software 112bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * distributed under the License is distributed on an "AS IS" BASIS, 122bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * See the License for the specific language governing permissions and 142bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * limitations under the License. 152bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 162bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 172bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochpackage com.example.android.bitmapfun.util; 182bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 192bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.content.Context; 202bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.graphics.Bitmap; 212bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.net.ConnectivityManager; 222bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.net.NetworkInfo; 2303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport android.os.Build; 242bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.util.Log; 252bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport android.widget.Toast; 262bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 272bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport com.example.android.bitmapfun.BuildConfig; 2803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport com.example.android.bitmapfun.R; 292bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 302bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.io.BufferedInputStream; 312bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.io.BufferedOutputStream; 322bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.io.File; 3303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.io.FileDescriptor; 3403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.io.FileInputStream; 352bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.io.IOException; 3603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Kochimport java.io.OutputStream; 372bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.net.HttpURLConnection; 382bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochimport java.net.URL; 392bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 402bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch/** 412bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * A simple subclass of {@link ImageResizer} that fetches and resizes images fetched from a URL. 422bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 432bab0137e0af92c374d3efb2ed0e1d894981e015Adam Kochpublic class ImageFetcher extends ImageResizer { 442bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch private static final String TAG = "ImageFetcher"; 452bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB 4603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private static final String HTTP_CACHE_DIR = "http"; 4703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private static final int IO_BUFFER_SIZE = 8 * 1024; 4803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 4903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private DiskLruCache mHttpDiskCache; 5003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private File mHttpCacheDir; 5103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private boolean mHttpDiskCacheStarting = true; 5203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private final Object mHttpDiskCacheLock = new Object(); 5303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private static final int DISK_CACHE_INDEX = 0; 542bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 552bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch /** 562bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * Initialize providing a target image width and height for the processing images. 572bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 582bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param context 592bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param imageWidth 602bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param imageHeight 612bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 622bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch public ImageFetcher(Context context, int imageWidth, int imageHeight) { 632bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch super(context, imageWidth, imageHeight); 642bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch init(context); 652bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 662bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 672bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch /** 682bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * Initialize providing a single target image size (used for both width and height); 692bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 702bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param context 712bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param imageSize 722bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 732bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch public ImageFetcher(Context context, int imageSize) { 742bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch super(context, imageSize); 752bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch init(context); 762bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 772bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 782bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch private void init(Context context) { 792bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch checkConnection(context); 8003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpCacheDir = ImageCache.getDiskCacheDir(context, HTTP_CACHE_DIR); 8103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 8203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 8303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch @Override 8403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch protected void initDiskCacheInternal() { 8503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch super.initDiskCacheInternal(); 8603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch initHttpDiskCache(); 8703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 8803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 8903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch private void initHttpDiskCache() { 9003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (!mHttpCacheDir.exists()) { 9103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpCacheDir.mkdirs(); 9203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 9303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch synchronized (mHttpDiskCacheLock) { 9403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (ImageCache.getUsableSpace(mHttpCacheDir) > HTTP_CACHE_SIZE) { 9503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 9603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache = DiskLruCache.open(mHttpCacheDir, 1, 1, HTTP_CACHE_SIZE); 9703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (BuildConfig.DEBUG) { 9803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.d(TAG, "HTTP cache initialized"); 9903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 10003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) { 10103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache = null; 10203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 10303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 10403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCacheStarting = false; 10503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCacheLock.notifyAll(); 10603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 10703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 10803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 10903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch @Override 11003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch protected void clearCacheInternal() { 11103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch super.clearCacheInternal(); 11203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch synchronized (mHttpDiskCacheLock) { 11303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (mHttpDiskCache != null && !mHttpDiskCache.isClosed()) { 11403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 11503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache.delete(); 11603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (BuildConfig.DEBUG) { 11703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.d(TAG, "HTTP cache cleared"); 11803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 11903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) { 12003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.e(TAG, "clearCacheInternal - " + e); 12103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 12203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache = null; 12303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCacheStarting = true; 12403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch initHttpDiskCache(); 12503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 12603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 12703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 12803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 12903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch @Override 13003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch protected void flushCacheInternal() { 13103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch super.flushCacheInternal(); 13203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch synchronized (mHttpDiskCacheLock) { 13303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (mHttpDiskCache != null) { 13403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 13503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache.flush(); 13603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (BuildConfig.DEBUG) { 13703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.d(TAG, "HTTP cache flushed"); 13803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 13903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) { 14003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.e(TAG, "flush - " + e); 14103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 14203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 14303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 14403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 14503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch 14603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch @Override 14703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch protected void closeCacheInternal() { 14803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch super.closeCacheInternal(); 14903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch synchronized (mHttpDiskCacheLock) { 15003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (mHttpDiskCache != null) { 15103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 15203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (!mHttpDiskCache.isClosed()) { 15303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache.close(); 15403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCache = null; 15503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (BuildConfig.DEBUG) { 15603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.d(TAG, "HTTP cache closed"); 15703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 15803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 15903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) { 16003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.e(TAG, "closeCacheInternal - " + e); 16103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 16203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 16303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 1642bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 1652bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 1662bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch /** 16703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Simple network connection check. 16803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * 16903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * @param context 17003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch */ 1712bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch private void checkConnection(Context context) { 1722bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch final ConnectivityManager cm = 1732bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 1742bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); 1752bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) { 17603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Toast.makeText(context, R.string.no_network_connection_toast, Toast.LENGTH_LONG).show(); 1772bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch Log.e(TAG, "checkConnection - no connection found"); 1782bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 1792bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 1802bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 1812bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch /** 1822bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * The main process method, which will be called by the ImageWorker in the AsyncTask background 1832bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * thread. 1842bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 1852bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param data The data to load the bitmap, in this case, a regular http URL 1862bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @return The downloaded and resized bitmap 1872bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 1882bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch private Bitmap processBitmap(String data) { 1892bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch if (BuildConfig.DEBUG) { 1902bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch Log.d(TAG, "processBitmap - " + data); 1912bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 1922bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 19303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch final String key = ImageCache.hashKeyForDisk(data); 19403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch FileDescriptor fileDescriptor = null; 19503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch FileInputStream fileInputStream = null; 19603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch DiskLruCache.Snapshot snapshot; 19703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch synchronized (mHttpDiskCacheLock) { 19803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch // Wait for disk cache to initialize 19903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch while (mHttpDiskCacheStarting) { 20003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 20103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch mHttpDiskCacheLock.wait(); 20203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (InterruptedException e) {} 20303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 2042bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 20503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (mHttpDiskCache != null) { 20603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 20703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch snapshot = mHttpDiskCache.get(key); 20803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (snapshot == null) { 20903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (BuildConfig.DEBUG) { 21003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.d(TAG, "processBitmap, not found in http cache, downloading..."); 21103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 21203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch DiskLruCache.Editor editor = mHttpDiskCache.edit(key); 21303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (editor != null) { 21403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (downloadUrlToStream(data, 21503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch editor.newOutputStream(DISK_CACHE_INDEX))) { 21603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch editor.commit(); 21703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } else { 21803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch editor.abort(); 21903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 22003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 22103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch snapshot = mHttpDiskCache.get(key); 22203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 22303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (snapshot != null) { 22403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch fileInputStream = 22503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX); 22603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch fileDescriptor = fileInputStream.getFD(); 22703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 22803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) { 22903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.e(TAG, "processBitmap - " + e); 23003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IllegalStateException e) { 23103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Log.e(TAG, "processBitmap - " + e); 23203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } finally { 23303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (fileDescriptor == null && fileInputStream != null) { 23403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 23503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch fileInputStream.close(); 23603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) {} 23703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 23803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 23903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 2402bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 2412bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 24203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch Bitmap bitmap = null; 24303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (fileDescriptor != null) { 24403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch bitmap = decodeSampledBitmapFromDescriptor(fileDescriptor, mImageWidth, mImageHeight); 24503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 24603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (fileInputStream != null) { 24703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 24803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch fileInputStream.close(); 24903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (IOException e) {} 25003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 25103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch return bitmap; 2522bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 2532bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 2542bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch @Override 2552bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch protected Bitmap processBitmap(Object data) { 2562bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch return processBitmap(String.valueOf(data)); 2572bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 2582bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 2592bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch /** 26003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Download a bitmap from a URL and write the content to an output stream. 2612bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * 2622bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch * @param urlString The URL to fetch 26303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * @return true if successful, false otherwise 2642bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch */ 26503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch public boolean downloadUrlToStream(String urlString, OutputStream outputStream) { 26603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch disableConnectionReuseIfNecessary(); 2672bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch HttpURLConnection urlConnection = null; 2682bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch BufferedOutputStream out = null; 26903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch BufferedInputStream in = null; 2702bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 2712bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch try { 2722bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch final URL url = new URL(urlString); 2732bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch urlConnection = (HttpURLConnection) url.openConnection(); 27403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE); 27503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE); 2762bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 2772bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch int b; 2782bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch while ((b = in.read()) != -1) { 2792bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch out.write(b); 2802bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 28103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch return true; 2822bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } catch (final IOException e) { 2832bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch Log.e(TAG, "Error in downloadBitmap - " + e); 2842bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } finally { 2852bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch if (urlConnection != null) { 2862bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch urlConnection.disconnect(); 2872bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 28803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch try { 28903ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (out != null) { 2902bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch out.close(); 2912bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 29203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (in != null) { 29303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch in.close(); 29403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 29503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } catch (final IOException e) {} 2962bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 29703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch return false; 29803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 2992bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch 30003ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch /** 30103ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * Workaround for bug pre-Froyo, see here for more info: 30203ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch * http://android-developers.blogspot.com/2011/09/androids-http-clients.html 30303ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch */ 30403ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch public static void disableConnectionReuseIfNecessary() { 30503ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch // HTTP connection reuse which was buggy pre-froyo 30603ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { 30703ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch System.setProperty("http.keepAlive", "false"); 30803ceb37f79e31626aaac5318b3143a2cfafaea42Adam Koch } 3092bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch } 3102bab0137e0af92c374d3efb2ed0e1d894981e015Adam Koch} 311