package vandy.mooc; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.util.Locale; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.provider.MediaStore.Images; import android.util.Base64; import android.util.Log; /** * This helper class encapsulates several static methods that are used * to download image files. */ public class DownloadUtils { /** * Used for debugging. */ private final static String TAG = "DownloadUtils"; /** * If you have access to a stable Internet connection for testing * purposes, feel free to change this variable to false so it * actually downloads the image from a remote server. */ static final boolean DOWNLOAD_OFFLINE = false; /** * The resource that we write to the file system in offline * mode. */ static final int OFFLINE_TEST_IMAGE = R.raw.dougs; /** * The file name that we should use to store the image in offline * mode. */ static final String OFFLINE_FILENAME = "dougs.jpg"; /** * Download the image located at the provided Internet url using * the URL class, store it on the android file system using a * FileOutputStream, and return the path to the image file on * disk. * * @param context the context in which to write the file. * @param url the web url. * * @return the absolute path to the downloaded image file on the file system. */ public static Uri downloadImage(Context context, Uri url) { try { if (!isExternalStorageWritable()) { Log.d(TAG, "external storage is not writable"); return null; } // Input stream. InputStream inputStream; // Filename that we're downloading (or opening). String filename; // If we're offline, open the image in our resources. if (DOWNLOAD_OFFLINE) { // Get a stream from the image resource. inputStream = context.getResources().openRawResource(OFFLINE_TEST_IMAGE); filename = OFFLINE_FILENAME; // Otherwise, download the file requested by the user. } else { // Download the contents at the URL, which should // reference an image. inputStream = (InputStream) new URL(url.toString()).getContent(); filename = url.toString(); } // Create an output file and save the image into it. return DownloadUtils.createDirectoryAndSaveFile (context, inputStream, filename); } catch (Exception e) { Log.e(TAG, "Exception while downloading. Returning null."); Log.e(TAG, e.toString()); e.printStackTrace(); return null; } } /** * Decode an InputStream into a Bitmap and store it in a file on * the device. * * @param context the context in which to write the file. * @param inputStream the Input Stream. * @param fileName name of the file. * * @return the absolute path to the downloaded image file on the file system. */ private static Uri createDirectoryAndSaveFile(Context context, InputStream inputStream, String fileName) { // Decode the InputStream into a Bitmap image. Bitmap imageToSave = BitmapFactory.decodeStream(inputStream); File directory = new File(Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DCIM) + "/ImageDir"); if (!directory.exists()) { File newDirectory = new File(directory.getAbsolutePath()); newDirectory.mkdirs(); } File file = new File(directory, getTemporaryFilename(fileName)); if (file.exists()) file.delete(); try { FileOutputStream outputStream = new FileOutputStream(file); imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); outputStream.flush(); outputStream.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); } // Get the absolute path of the image. String absolutePathToImage = file.getAbsolutePath(); // Provide metadata so the downloaded image is viewable in the // Gallery. ContentValues values = new ContentValues(); values.put(Images.Media.TITLE, fileName); values.put(Images.Media.DESCRIPTION, fileName); values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis ()); values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US)); values.put("_data", absolutePathToImage); ContentResolver cr = context.getContentResolver(); // Store the metadata for the image into the Gallery. cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); Log.d(TAG, "absolute path to image file is " + absolutePathToImage); return Uri.parse(absolutePathToImage); } /** * This method checks if we can write image to external storage * * @return true if an image can be written, and false otherwise */ private static boolean isExternalStorageWritable() { return Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState()); } /** * Create a temporary filename to store the result of a download. * * @param url Name of the URL. * @return String containing the temporary filename. */ static private String getTemporaryFilename(final String url) { // This is what you'd normally call to get a unique temporary // filename, but for testing purposes we always name the file // the same to avoid filling up student phones with numerous // files! // // return Base64.encodeToString(url.getBytes(), // Base64.NO_WRAP) // + System.currentTimeMillis()); return Base64.encodeToString(url.getBytes(), Base64.NO_WRAP); } }