org.appspot.apprtc.util.ThumbnailsCacheManager.java Source code

Java tutorial

Introduction

Here is the source code for org.appspot.apprtc.util.ThumbnailsCacheManager.java

Source

/**
 *   ownCloud Android client application
 *
 *   @author Tobias Kaminsky
 *   @author David A. Velasco
 *   Copyright (C) 2015 ownCloud Inc.
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   as published by the Free Software Foundation.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package org.appspot.apprtc.util;

import android.accounts.Account;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.util.Log;
import android.view.MenuItem;
import android.widget.ImageView;

import org.appspot.apprtc.R;

import java.io.File;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Locale;
import java.util.concurrent.RejectedExecutionException;

/**
 * Manager for concurrent access to thumbnails cache.
 */
public class ThumbnailsCacheManager {

    private static final String TAG = ThumbnailsCacheManager.class.getSimpleName();

    private static final String CACHE_FOLDER = "thumbnailCache";

    private static final Object mThumbnailsDiskCacheLock = new Object();
    private static DiskLruImageCache mThumbnailCache = null;
    private static boolean mThumbnailCacheStarting = true;

    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
    private static final CompressFormat mCompressFormat = CompressFormat.JPEG;
    private static final int mCompressQuality = 70;
    private static Context mAppContext;

    static public void ThumbnailsCacheManagerInit(Context context) {
        synchronized (mThumbnailsDiskCacheLock) {
            mAppContext = context;

            if (mThumbnailCacheStarting) {
                // initialise thumbnails cache on background thread
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        new InitDiskCacheTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
                    } else {
                        new InitDiskCacheTask().execute();
                    }
                } catch (RejectedExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static class InitDiskCacheTask extends AsyncTask<File, Void, Void> {

        @Override
        protected Void doInBackground(File... params) {
            synchronized (mThumbnailsDiskCacheLock) {
                mThumbnailCacheStarting = true;

                if (mThumbnailCache == null) {
                    try {
                        // Check if media is mounted or storage is built-in, if so,
                        // try and use external cache dir; otherwise use internal cache dir
                        final String cachePath = mAppContext.getExternalCacheDir().getPath() + File.separator
                                + CACHE_FOLDER;
                        final File diskCacheDir = new File(cachePath);
                        mThumbnailCache = new DiskLruImageCache(diskCacheDir, DISK_CACHE_SIZE, mCompressFormat,
                                mCompressQuality);
                    } catch (Exception e) {
                        e.printStackTrace();
                        mThumbnailCache = null;
                    }
                }
                mThumbnailCacheStarting = false; // Finished initialization
                mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
            }
            return null;
        }
    }

    /**
     * Add thumbnail to cache
     * @param imageKey: thumb key
     * @param bitmap:   image for extracting thumbnail
     * @param path:     image path
     * @param px:       thumbnail dp
     * @return Bitmap
     */
    private static Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px) {

        Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);

        // Add thumbnail to cache
        addBitmapToCache(imageKey, thumbnail);

        return thumbnail;
    }

    public static void addBitmapToCache(String key, Bitmap bitmap) {
        synchronized (mThumbnailsDiskCacheLock) {
            if (mThumbnailCache != null) {
                mThumbnailCache.put(key, bitmap);
            }
        }
    }

    public static Bitmap getBitmapFromDiskCache(String key) {
        synchronized (mThumbnailsDiskCacheLock) {
            // Wait while disk cache is started from background thread
            while (mThumbnailCacheStarting) {
                try {
                    mThumbnailsDiskCacheLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (mThumbnailCache != null) {
                return mThumbnailCache.getBitmap(key);
            }
        }
        return null;
    }

    public static void LoadImage(final String url, ImageView image, final String displayname, final boolean rounded,
            boolean fromCache) {
        final WeakReference<ImageView> imageView = new WeakReference<ImageView>(image);
        final Handler uiHandler = new Handler();
        final int FG_COLOR = 0xFFFAFAFA;
        final String name = displayname;

        if (fromCache) {
            Bitmap bitmap = ThumbnailsCacheManager.getBitmapFromDiskCache(url);

            if (bitmap != null) {
                if (rounded) {
                    RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory
                            .create(imageView.get().getResources(), bitmap);
                    roundedBitmap.setCircular(true);
                    imageView.get().setImageDrawable(roundedBitmap);
                } else {
                    imageView.get().setImageBitmap(bitmap);
                }
                imageView.get().setContentDescription(displayname);
                return;
            }
        }

        AsyncHttpURLConnection httpConnection = new AsyncHttpURLConnection("GET", url, "",
                new AsyncHttpURLConnection.AsyncHttpEvents() {
                    @Override
                    public void onHttpError(String errorMessage) {
                        Log.d("LoadImage", errorMessage);
                    }

                    @Override
                    public void onHttpComplete(String response) {
                        int size = 96;
                        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
                        Canvas canvas = new Canvas(bitmap);
                        final String trimmedName = name == null ? "" : name.trim();
                        drawTile(canvas, trimmedName, 0, 0, size, size);
                        ThumbnailsCacheManager.addBitmapToCache(url, bitmap);

                        onHttpComplete(bitmap);
                    }

                    @Override
                    public void onHttpComplete(final Bitmap response) {
                        if (imageView != null && imageView.get() != null) {
                            uiHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (imageView.get() != null) {
                                        if (rounded) {
                                            RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory
                                                    .create(imageView.get().getResources(), response);
                                            roundedBitmap.setCircular(true);
                                            imageView.get().setImageDrawable(roundedBitmap);
                                        } else {
                                            imageView.get().setImageBitmap(response);
                                        }
                                        imageView.get().setContentDescription(displayname);
                                    }

                                }

                            });

                        }
                    }

                    private boolean drawTile(Canvas canvas, String letter, int tileColor, int left, int top,
                            int right, int bottom) {
                        letter = letter.toUpperCase(Locale.getDefault());
                        Paint tilePaint = new Paint(), textPaint = new Paint();
                        tilePaint.setColor(tileColor);
                        textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                        textPaint.setColor(FG_COLOR);
                        textPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
                        textPaint.setTextSize((float) ((right - left) * 0.8));
                        Rect rect = new Rect();

                        canvas.drawRect(new Rect(left, top, right, bottom), tilePaint);
                        textPaint.getTextBounds(letter, 0, 1, rect);
                        float width = textPaint.measureText(letter);
                        canvas.drawText(letter, (right + left) / 2 - width / 2,
                                (top + bottom) / 2 + rect.height() / 2, textPaint);
                        return true;
                    }

                    private boolean drawTile(Canvas canvas, String name, int left, int top, int right, int bottom) {
                        if (name != null) {
                            final String letter = getFirstLetter(name);
                            final int color = ThumbnailsCacheManager.getColorForName(name);
                            drawTile(canvas, letter, color, left, top, right, bottom);
                            return true;
                        }
                        return false;
                    }

                });
        httpConnection.setBitmap();
        httpConnection.send();
    }

    public interface LoadImageCallback {
        void onImageLoaded(Bitmap bitmap);
    }

    public static void LoadImage(final String url, LoadImageCallback callback, final Resources resources,
            final String displayname, final boolean rounded, boolean fromCache) {
        final LoadImageCallback mCallback = callback;
        final Handler uiHandler = new Handler();
        final int FG_COLOR = 0xFFFAFAFA;
        final String name = displayname;

        if (fromCache) {
            Bitmap bitmap = ThumbnailsCacheManager.getBitmapFromDiskCache(url);

            if (bitmap != null) {
                if (rounded) {
                    RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory.create(resources, bitmap);
                    roundedBitmap.setCircular(true);
                    mCallback.onImageLoaded(roundedBitmap.getBitmap());
                } else {
                    mCallback.onImageLoaded(bitmap);
                }
                return;
            }
        }

        AsyncHttpURLConnection httpConnection = new AsyncHttpURLConnection("GET", url, "",
                new AsyncHttpURLConnection.AsyncHttpEvents() {
                    @Override
                    public void onHttpError(String errorMessage) {
                        Log.d("LoadImage", errorMessage);
                    }

                    @Override
                    public void onHttpComplete(String response) {
                        int size = 256;
                        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
                        Canvas canvas = new Canvas(bitmap);
                        final String trimmedName = name == null ? "" : name.trim();
                        drawTile(canvas, trimmedName, 0, 0, size, size);
                        ThumbnailsCacheManager.addBitmapToCache(url, bitmap);
                        onHttpComplete(bitmap);
                    }

                    @Override
                    public void onHttpComplete(final Bitmap response) {
                        if (mCallback != null) {
                            uiHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (rounded) {
                                        RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory
                                                .create(resources, response);
                                        roundedBitmap.setCircular(true);
                                        mCallback.onImageLoaded(roundedBitmap.getBitmap());
                                    } else {
                                        mCallback.onImageLoaded(response);
                                    }

                                }

                            });

                        }
                    }

                    private boolean drawTile(Canvas canvas, String letter, int tileColor, int left, int top,
                            int right, int bottom) {
                        letter = letter.toUpperCase(Locale.getDefault());
                        Paint tilePaint = new Paint(), textPaint = new Paint();
                        tilePaint.setColor(tileColor);
                        textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                        textPaint.setColor(FG_COLOR);
                        textPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
                        textPaint.setTextSize((float) ((right - left) * 0.8));
                        Rect rect = new Rect();

                        canvas.drawRect(new Rect(left, top, right, bottom), tilePaint);
                        textPaint.getTextBounds(letter, 0, 1, rect);
                        float width = textPaint.measureText(letter);
                        canvas.drawText(letter, (right + left) / 2 - width / 2,
                                (top + bottom) / 2 + rect.height() / 2, textPaint);
                        return true;
                    }

                    private boolean drawTile(Canvas canvas, String name, int left, int top, int right, int bottom) {
                        if (name != null) {
                            final String letter = getFirstLetter(name);
                            final int color = ThumbnailsCacheManager.getColorForName(name);
                            drawTile(canvas, letter, color, left, top, right, bottom);
                            return true;
                        }
                        return false;
                    }

                });
        httpConnection.setBitmap();
        httpConnection.send();
    }

    public static void LoadMenuImage(final String url, MenuItem menuItem, String displayname, final boolean rounded,
            Resources resources, boolean fromCache) {
        final Resources mResources = resources;
        final WeakReference<MenuItem> menuItemImage = new WeakReference<MenuItem>(menuItem);
        final Handler uiHandler = new Handler();
        final int FG_COLOR = 0xFFFAFAFA;
        final String name = displayname;

        if (fromCache) {
            Bitmap bitmap = ThumbnailsCacheManager.getBitmapFromDiskCache(url);

            if (bitmap != null) {
                if (rounded) {
                    RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory.create(mResources, bitmap);
                    roundedBitmap.setCircular(true);
                    menuItemImage.get().setIcon(roundedBitmap);
                } else {
                    menuItemImage.get().setIcon(new BitmapDrawable(bitmap));
                }
                return;
            }
        }

        AsyncHttpURLConnection httpConnection = new AsyncHttpURLConnection("GET", url, "",
                new AsyncHttpURLConnection.AsyncHttpEvents() {
                    @Override
                    public void onHttpError(String errorMessage) {
                        Log.d("LoadImage", errorMessage);
                    }

                    @Override
                    public void onHttpComplete(String response) {
                        int size = 96;
                        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
                        Canvas canvas = new Canvas(bitmap);
                        final String trimmedName = name == null ? "" : name.trim();
                        drawTile(canvas, trimmedName, 0, 0, size, size);
                        ThumbnailsCacheManager.addBitmapToCache(url, bitmap);
                        onHttpComplete(bitmap);
                    }

                    @Override
                    public void onHttpComplete(final Bitmap response) {
                        if (menuItemImage != null && menuItemImage.get() != null) {
                            uiHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    if (rounded) {
                                        RoundedBitmapDrawable roundedBitmap = RoundedBitmapDrawableFactory
                                                .create(mResources, response);
                                        roundedBitmap.setCircular(true);
                                        menuItemImage.get().setIcon(roundedBitmap);
                                    } else {
                                        menuItemImage.get().setIcon(new BitmapDrawable(response));
                                    }
                                }

                            });

                        }
                    }

                    private boolean drawTile(Canvas canvas, String letter, int tileColor, int left, int top,
                            int right, int bottom) {
                        letter = letter.toUpperCase(Locale.getDefault());
                        Paint tilePaint = new Paint(), textPaint = new Paint();
                        tilePaint.setColor(tileColor);
                        textPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
                        textPaint.setColor(FG_COLOR);
                        textPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
                        textPaint.setTextSize((float) ((right - left) * 0.8));
                        Rect rect = new Rect();

                        canvas.drawRect(new Rect(left, top, right, bottom), tilePaint);
                        textPaint.getTextBounds(letter, 0, 1, rect);
                        float width = textPaint.measureText(letter);
                        canvas.drawText(letter, (right + left) / 2 - width / 2,
                                (top + bottom) / 2 + rect.height() / 2, textPaint);
                        return true;
                    }

                    private boolean drawTile(Canvas canvas, String name, int left, int top, int right, int bottom) {
                        if (name != null) {
                            final String letter = getFirstLetter(name);
                            final int color = ThumbnailsCacheManager.getColorForName(name);
                            drawTile(canvas, letter, color, left, top, right, bottom);
                            return true;
                        }
                        return false;
                    }

                });
        httpConnection.setBitmap();
        httpConnection.send();
    }

    public static int getColorForName(String name) {
        if (name == null || name.isEmpty()) {
            return 0xFF202020;
        }
        int colors[] = { 0xFFe91e63, 0xFF9c27b0, 0xFF673ab7, 0xFF3f51b5, 0xFF5677fc, 0xFF03a9f4, 0xFF00bcd4,
                0xFF009688, 0xFFff5722, 0xFF795548, 0xFF607d8b };
        return colors[(int) ((name.hashCode() & 0xffffffffl) % colors.length)];
    }

    public static String getFirstLetter(String name) {
        for (Character c : name.toCharArray()) {
            if (Character.isLetterOrDigit(c)) {
                return c.toString();
            }
        }
        return "X";
    }
}