1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.bitmapfun.util; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.net.ConnectivityManager; 22 import android.net.NetworkInfo; 23 import android.util.Log; 24 import android.widget.Toast; 25 26 import com.example.android.bitmapfun.BuildConfig; 27 28 import java.io.BufferedInputStream; 29 import java.io.BufferedOutputStream; 30 import java.io.File; 31 import java.io.FileOutputStream; 32 import java.io.IOException; 33 import java.io.InputStream; 34 import java.net.HttpURLConnection; 35 import java.net.URL; 36 37 /** 38 * A simple subclass of {@link ImageResizer} that fetches and resizes images fetched from a URL. 39 */ 40 public class ImageFetcher extends ImageResizer { 41 private static final String TAG = "ImageFetcher"; 42 private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB 43 public static final String HTTP_CACHE_DIR = "http"; 44 45 /** 46 * Initialize providing a target image width and height for the processing images. 47 * 48 * @param context 49 * @param imageWidth 50 * @param imageHeight 51 */ ImageFetcher(Context context, int imageWidth, int imageHeight)52 public ImageFetcher(Context context, int imageWidth, int imageHeight) { 53 super(context, imageWidth, imageHeight); 54 init(context); 55 } 56 57 /** 58 * Initialize providing a single target image size (used for both width and height); 59 * 60 * @param context 61 * @param imageSize 62 */ ImageFetcher(Context context, int imageSize)63 public ImageFetcher(Context context, int imageSize) { 64 super(context, imageSize); 65 init(context); 66 } 67 init(Context context)68 private void init(Context context) { 69 checkConnection(context); 70 } 71 72 /** 73 * Simple network connection check. 74 * 75 * @param context 76 */ checkConnection(Context context)77 private void checkConnection(Context context) { 78 final ConnectivityManager cm = 79 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 80 final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); 81 if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) { 82 Toast.makeText(context, "No network connection found.", Toast.LENGTH_LONG).show(); 83 Log.e(TAG, "checkConnection - no connection found"); 84 } 85 } 86 87 /** 88 * The main process method, which will be called by the ImageWorker in the AsyncTask background 89 * thread. 90 * 91 * @param data The data to load the bitmap, in this case, a regular http URL 92 * @return The downloaded and resized bitmap 93 */ processBitmap(String data)94 private Bitmap processBitmap(String data) { 95 if (BuildConfig.DEBUG) { 96 Log.d(TAG, "processBitmap - " + data); 97 } 98 99 // Download a bitmap, write it to a file 100 final File f = downloadBitmap(mContext, data); 101 102 if (f != null) { 103 // Return a sampled down version 104 return decodeSampledBitmapFromFile(f.toString(), mImageWidth, mImageHeight); 105 } 106 107 return null; 108 } 109 110 @Override processBitmap(Object data)111 protected Bitmap processBitmap(Object data) { 112 return processBitmap(String.valueOf(data)); 113 } 114 115 /** 116 * Download a bitmap from a URL, write it to a disk and return the File pointer. This 117 * implementation uses a simple disk cache. 118 * 119 * @param context The context to use 120 * @param urlString The URL to fetch 121 * @return A File pointing to the fetched bitmap 122 */ downloadBitmap(Context context, String urlString)123 public static File downloadBitmap(Context context, String urlString) { 124 final File cacheDir = DiskLruCache.getDiskCacheDir(context, HTTP_CACHE_DIR); 125 126 final DiskLruCache cache = 127 DiskLruCache.openCache(context, cacheDir, HTTP_CACHE_SIZE); 128 129 final File cacheFile = new File(cache.createFilePath(urlString)); 130 131 if (cache.containsKey(urlString)) { 132 if (BuildConfig.DEBUG) { 133 Log.d(TAG, "downloadBitmap - found in http cache - " + urlString); 134 } 135 return cacheFile; 136 } 137 138 if (BuildConfig.DEBUG) { 139 Log.d(TAG, "downloadBitmap - downloading - " + urlString); 140 } 141 142 Utils.disableConnectionReuseIfNecessary(); 143 HttpURLConnection urlConnection = null; 144 BufferedOutputStream out = null; 145 146 try { 147 final URL url = new URL(urlString); 148 urlConnection = (HttpURLConnection) url.openConnection(); 149 final InputStream in = 150 new BufferedInputStream(urlConnection.getInputStream(), Utils.IO_BUFFER_SIZE); 151 out = new BufferedOutputStream(new FileOutputStream(cacheFile), Utils.IO_BUFFER_SIZE); 152 153 int b; 154 while ((b = in.read()) != -1) { 155 out.write(b); 156 } 157 158 return cacheFile; 159 160 } catch (final IOException e) { 161 Log.e(TAG, "Error in downloadBitmap - " + e); 162 } finally { 163 if (urlConnection != null) { 164 urlConnection.disconnect(); 165 } 166 if (out != null) { 167 try { 168 out.close(); 169 } catch (final IOException e) { 170 Log.e(TAG, "Error in downloadBitmap - " + e); 171 } 172 } 173 } 174 175 return null; 176 } 177 } 178