• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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