// // _/_/_/ _/ _/_/_/_/_/ // _/ _/_/ _/_/ _/ _/ _/ _/_/ _/_/ // _/ _/_/ _/_/_/_/ _/_/_/_/ _/_/ _/ _/ _/ _/ _/ // _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ // _/_/_/ _/_/_/ _/_/_/ _/ _/ _/_/_/_/_/ _/_/ _/_/ // // // Copyright (c) 2015-2016, Geek Zoo Studio // http://www.geek-zoo.com // // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. // package com.BeeFramework.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import java.io.*; import java.lang.ref.SoftReference; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Date; import java.util.HashMap; import java.util.Map; public class WebImageCache { private final static String TAG = WebImageCache.class.getSimpleName(); // cache rules private static boolean mIsMemoryCachingEnabled = true; private static boolean mIsDiskCachingEnabled = true; private static int mDefaultDiskCacheTimeoutInSeconds = 60 * 60 * 24; // one day default private Map<String, SoftReference<Bitmap>> mMemCache; public WebImageCache() { mMemCache = new HashMap<String, SoftReference<Bitmap>>(); } public static void setMemoryCachingEnabled(boolean enabled) { mIsMemoryCachingEnabled = enabled; Log.v(TAG, "Memory cache " + (enabled ? "enabled" : "disabled") + "."); } public static void setDiskCachingEnabled(boolean enabled) { mIsDiskCachingEnabled = enabled; Log.v(TAG, "Disk cache " + (enabled ? "enabled" : "disabled") + "."); } public static void setDiskCachingDefaultCacheTimeout(int seconds) { mDefaultDiskCacheTimeoutInSeconds = seconds; Log.v(TAG, "Disk cache timeout set to " + seconds + " seconds."); } public Bitmap getBitmapFromMemCache(String urlString) { if (mIsMemoryCachingEnabled) { synchronized (mMemCache) { SoftReference<Bitmap> bitmapRef = mMemCache.get(urlString); if (bitmapRef != null) { Bitmap bitmap = bitmapRef.get(); if (bitmap == null) { mMemCache.remove(urlString); Log.v(TAG, "Expiring memory cache for URL " + urlString + "."); } else { Log.v(TAG, "Retrieved " + urlString + " from memory cache."); return bitmap; } } } } return null; } public Bitmap getBitmapFromDiskCache(Context context, String urlString, int diskCacheTimeoutInSeconds) { if (mIsDiskCachingEnabled) { Bitmap bitmap = null; File path = context.getCacheDir(); InputStream is = null; String hashedURLString = hashURLString(urlString); // correct timeout if (diskCacheTimeoutInSeconds < 0) { diskCacheTimeoutInSeconds = mDefaultDiskCacheTimeoutInSeconds; } File file = new File(path, hashedURLString); if (file.exists() && file.canRead()) { // check for timeout if ((file.lastModified() + (diskCacheTimeoutInSeconds * 1000L)) < new Date().getTime()) { Log.v(TAG, "Expiring disk cache (TO: " + diskCacheTimeoutInSeconds + "s) for URL " + urlString); // expire file.delete(); } else { try { is = new FileInputStream(file); bitmap = BitmapFactory.decodeStream(is); Log.v(TAG, "Retrieved " + urlString + " from disk cache (TO: " + diskCacheTimeoutInSeconds + "s)."); } catch (Exception ex) { Log.e(TAG, "Could not retrieve " + urlString + " from disk cache: " + ex.toString()); } finally { try { is.close(); } catch (Exception ex) {} } } } return bitmap; } return null; } public void addBitmapToMemCache(String urlString, Bitmap bitmap) { if (mIsMemoryCachingEnabled) { synchronized (mMemCache) { mMemCache.put(urlString, new SoftReference<Bitmap>(bitmap)); } } } public void addBitmapToCache(Context context, String urlString, Bitmap bitmap) { // mem cache addBitmapToMemCache(urlString, bitmap); // disk cache // TODO: manual cache cleanup if (mIsDiskCachingEnabled) { File path = context.getCacheDir(); OutputStream os = null; String hashedURLString = hashURLString(urlString); try { // NOWORKY File tmpFile = File.createTempFile("wic.", null); File file = new File(path, hashedURLString); os = new FileOutputStream(file.getAbsolutePath()); bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); os.flush(); os.close(); // NOWORKY tmpFile.renameTo(file); } catch (Exception ex) { Log.e(TAG, "Could not store " + urlString + " to disk cache: " + ex.toString()); } finally { try { os.close(); } catch (Exception ex) {} } } } private String hashURLString(String urlString) { try { // Create MD5 Hash MessageDigest digest = MessageDigest.getInstance("MD5"); digest.update(urlString.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); for (int i=0; i<messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } //fall back to old method return urlString.replaceAll("[^A-Za-z0-9]", "#"); } }