com.pizidea.imagepicker.AndroidImagePicker.java Source code

Java tutorial

Introduction

Here is the source code for com.pizidea.imagepicker.AndroidImagePicker.java

Source

/*
 *
 *  * Copyright (C) 2015 Eason.Lai (easonline7@gmail.com)
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 *
 */

package com.pizidea.imagepicker;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;

import com.pizidea.imagepicker.bean.ImageItem;
import com.pizidea.imagepicker.bean.ImageSet;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

/**
 * <b>The main Entrance of this lib</b><br/>
 * Created by Eason.Lai on 2015/11/1 10:42 <br/>
 * contacteasonline7@gmail.com <br/>
 */
public class AndroidImagePicker {
    public static final String TAG = AndroidImagePicker.class.getSimpleName();

    public static final int REQ_CAMERA = 1431;
    public static final int REQ_PREVIEW = 2347;

    public static final String KEY_PIC_PATH = "key_pic_path";
    public static final String KEY_PIC_SELECTED_POSITION = "key_pic_selected";

    private static AndroidImagePicker mInstance;

    public static AndroidImagePicker getInstance() {
        if (mInstance == null) {
            synchronized (AndroidImagePicker.class) {
                if (mInstance == null) {
                    mInstance = new AndroidImagePicker();
                }
            }
        }
        return mInstance;
    }

    private int selectLimit = 9;//can select 9 at most,you can change it yourself

    public int getSelectLimit() {
        return selectLimit;
    }

    public void setSelectLimit(int selectLimit) {
        this.selectLimit = selectLimit;
    }

    private int selectMode = Select_Mode.MODE_MULTI;//Select mode:single or multi

    public int getSelectMode() {
        return selectMode;
    }

    public void setSelectMode(int selectMode) {
        this.selectMode = selectMode;
    }

    private boolean shouldShowCamera = true;//indicate whether to show the camera item

    public boolean isShouldShowCamera() {
        return shouldShowCamera;
    }

    public void setShouldShowCamera(boolean shouldShowCamera) {
        this.shouldShowCamera = shouldShowCamera;
    }

    private String mCurrentPhotoPath;//image saving path when taking pictures

    public String getCurrentPhotoPath() {
        return mCurrentPhotoPath;
    }

    /**
     * Listeners of image selected changes,if you want to custom the Activity of ImagesGrid or ImagePreview,you might use it.
     */
    private List<OnImageSelectedListener> mImageSelectedListeners;

    public synchronized void addOnImageSelectedListener(OnImageSelectedListener l) {
        if (mImageSelectedListeners == null) {
            mImageSelectedListeners = new ArrayList<>();
            Log.i(TAG, "=====create new ImageSelectedListener List");
        }
        if (l != null) {
            this.mImageSelectedListeners.add(l);
            Log.i(TAG, "=====addOnImageSelectedListener:" + l.getClass().toString());
        }

    }

    public void removeOnImageItemSelectedListener(OnImageSelectedListener l) {
        if (mImageSelectedListeners == null) {
            return;
        }
        if (l != null && this.mImageSelectedListeners.size() > 0) {
            this.mImageSelectedListeners.remove(l);
            Log.i(TAG, "=====remove from mImageSelectedListeners:" + l.getClass().toString());
        }
    }

    private void notifyImageSelectedChanged(int position, ImageItem item, boolean isAdd) {
        if ((isAdd && getSelectImageCount() > selectLimit) || (!isAdd && getSelectImageCount() == selectLimit)) {
            //do not call the listeners if reached the select limit when selecting
            Log.i(TAG, "=====ignore notifyImageSelectedChanged:isAdd?" + isAdd);
        } else {
            if (mImageSelectedListeners == null || mImageSelectedListeners.size() <= 0) {
                return;
            }
            if (item != null) {
                Log.i(TAG, "=====notify mImageSelectedListeners:item=" + item.path);
                for (OnImageSelectedListener l : mImageSelectedListeners) {
                    l.onImageSelected(position, item, mSelectedImages.size(), selectLimit);
                }
            }

        }
    }

    /**
     * listeners of image crop complete
     */
    private List<OnImageCropCompleteListener> mImageCropCompleteListeners;

    public synchronized void addOnImageCropCompleteListener(OnImageCropCompleteListener l) {
        if (mImageCropCompleteListeners == null) {
            mImageCropCompleteListeners = new ArrayList<>();
            Log.i(TAG, "=====create new ImageCropCompleteListener List");
        }
        if (l != null) {
            this.mImageCropCompleteListeners.add(l);
            Log.i(TAG, "=====addOnImageCropCompleteListener:" + l.getClass().toString());
        }
    }

    public void removeOnImageCropCompleteListener(OnImageCropCompleteListener l) {
        if (mImageCropCompleteListeners == null) {
            return;
        }
        if (l != null && mImageCropCompleteListeners.size() > 0) {
            this.mImageCropCompleteListeners.remove(l);
            Log.i(TAG, "=====remove mImageCropCompleteListeners:" + l.getClass().toString());
        }

    }

    public synchronized void notifyImageCropComplete(Bitmap bmp, int ratio) {
        if (mImageCropCompleteListeners != null && mImageCropCompleteListeners.size() > 0 && bmp != null) {
            Log.i(TAG, "=====notify onImageCropCompleteListener  bitmap=" + bmp.toString() + "  ratio=" + ratio);
            for (OnImageCropCompleteListener l : mImageCropCompleteListeners) {
                l.onImageCropComplete(bmp, ratio);
            }
        }
    }

    /**
     * listener of picture taken
     */
    private ArrayList<OnPictureTakeCompleteListener> mOnPictureTakeCompleteListeners;

    public synchronized void setOnPictureTakeCompleteListener(OnPictureTakeCompleteListener l) {
        if (mOnPictureTakeCompleteListeners == null) {
            mOnPictureTakeCompleteListeners = new ArrayList<OnPictureTakeCompleteListener>();
        }
        if (l != null) {
            this.mOnPictureTakeCompleteListeners.add(l);
            Log.i(TAG, "=====setOnPictureTakeCompleteListener:" + l.getClass().toString());
        }

    }

    public synchronized void removeOnPictureTakeCompleteListener(OnPictureTakeCompleteListener l) {
        if (mOnPictureTakeCompleteListeners == null) {
            return;
        }
        if (l != null && mOnPictureTakeCompleteListeners.size() > 0) {
            this.mOnPictureTakeCompleteListeners.remove(l);
        }

    }

    public synchronized void notifyPictureTaken() {
        if (mOnPictureTakeCompleteListeners != null && mOnPictureTakeCompleteListeners.size() > 0) {
            for (OnPictureTakeCompleteListener l : mOnPictureTakeCompleteListeners) {
                l.onPictureTakeComplete(mCurrentPhotoPath);
            }

            Log.i(TAG, "=====notify mOnPictureTakeCompleteListener path=" + mCurrentPhotoPath);
        }
    }

    /**
     * Listener when image pick completed
     */
    private OnImagePickCompleteListener mOnImagePickCompleteListener;

    public synchronized void setOnImagePickCompleteListener(OnImagePickCompleteListener l) {
        if (l != null) {
            this.mOnImagePickCompleteListener = l;
            Log.i(TAG, "=====setOnImagePickCompleteListener:" + l.getClass().toString());
        }
    }

    public synchronized void deleteOnImagePickCompleteListener(OnImagePickCompleteListener l) {
        if (l != null) {
            mOnImagePickCompleteListener = null;
            Log.i(TAG, "=====remove mOnImagePickCompleteListener:" + l.getClass().toString());
            System.gc();
        }
    }

    public synchronized void notifyOnImagePickComplete(List<ImageItem> items) {
        if (mOnImagePickCompleteListener != null && items != null) {
            mOnImagePickCompleteListener.onImagePickComplete(items);
            Log.i(TAG, "=====notify mOnImagePickCompleteListener:selected size=" + items.size());
        }
    }

    private OnImagePageSelectedListener mOnImagePageSelectedListener;

    public void setOnImagePageSelectedListener(OnImagePageSelectedListener l) {
        if (l != null) {
            this.mOnImagePageSelectedListener = l;
            Log.i(TAG, "=====setOnImagePickCompleteListener:" + l.getClass().toString());
        }
    }

    public void deleteOnImagePageSelectedListener(OnImagePageSelectedListener l) {
        if (l != null) {
            mOnImagePageSelectedListener = null;
            Log.i(TAG, "=====remove mOnImagePickCompleteListener:" + l.getClass().toString());
            System.gc();
        }
    }

    public void notifyOnImagePageSelectedListener(List<ImageItem> items) {
        if (mOnImagePageSelectedListener != null && items != null) {
            mOnImagePageSelectedListener.onImagePageSelected(items);
            Log.i(TAG, "=====notify mOnImagePickCompleteListener:selected size=" + items.size());
        }
    }

    //All Images collect by Set
    private List<ImageSet> mImageSets;
    private int mCurrentSelectedImageSetPosition = 0;//Item 0: all images

    Set<ImageItem> mSelectedImages = new LinkedHashSet<>();;

    public List<ImageSet> getImageSets() {
        return mImageSets;
    }

    public List<ImageItem> getImageItemsOfCurrentImageSet() {
        return mImageSets.get(mCurrentSelectedImageSetPosition).imageItems;
    }

    public void setImageSets(List<ImageSet> mImageSets) {
        this.mImageSets = mImageSets;
    }

    public int getCurrentSelectedImageSetPosition() {
        return mCurrentSelectedImageSetPosition;
    }

    public void setCurrentSelectedImageSetPosition(int mCurrentSelectedImageSetPosition) {
        this.mCurrentSelectedImageSetPosition = mCurrentSelectedImageSetPosition;
    }

    public void addSelectedImageItem(int position, ImageItem item) {
        //mSelectedImages.put(position, item);
        if (mSelectedImages != null && item != null && position > -1) {
            mSelectedImages.add(item);
            Log.i(TAG, "=====select:" + item.path);
            notifyImageSelectedChanged(position, item, true);
        }
    }

    public void deleteSelectedImageItem(int position, ImageItem item) {
        if (mSelectedImages != null && item != null && position > -1) {
            mSelectedImages.remove(item);
            Log.i(TAG, "=====cancel select:" + item.path);
            notifyImageSelectedChanged(position, item, false);
        }
    }

    public boolean isSelect(int position, ImageItem item) {
        if (item == null) {
            return false;
        }
        if (mSelectedImages.contains(item)) {
            return true;
        }
        return false;
    }

    public int getSelectImageCount() {
        if (mSelectedImages == null) {
            return 0;
        }
        return mSelectedImages.size();
    }

    public void clear() {
        if (mImageSelectedListeners != null) {
            mImageSelectedListeners.clear();
            mImageSelectedListeners = null;
        }
        if (mImageCropCompleteListeners != null) {
            mImageCropCompleteListeners.clear();
            mImageCropCompleteListeners = null;
        }

        //mSelectedImages.clear();
        //mSelectedImages = null;

        if (mImageSets != null) {
            mImageSets.clear();
            mImageSets = null;
        }

        mCurrentSelectedImageSetPosition = 0;

        Log.i(TAG, "=====destroy:clear all data and listeners");
    }

    public List<ImageItem> getSelectedImages() {
        List<ImageItem> list = new ArrayList<>();
        list.addAll(mSelectedImages);
        return list;
    }

    public void deleteSelectedImages(int postion) {
        if (mSelectedImages != null && mSelectedImages.size() > 0) {
            mSelectedImages.remove(postion);
            Log.i(TAG, "=====clear all selected images");
        }
    }

    public void clearSelectedImages() {
        if (mSelectedImages != null) {
            mSelectedImages.clear();
            Log.i(TAG, "=====clear all selected images");
        }
    }

    public static Bitmap makeCropBitmap(Bitmap bitmap, Rect rectBox, RectF imageMatrixRect, int expectSize) {
        Bitmap bmp = bitmap;
        RectF localRectF = imageMatrixRect;
        float f = localRectF.width() / bmp.getWidth();
        int left = (int) ((rectBox.left - localRectF.left) / f);
        int top = (int) ((rectBox.top - localRectF.top) / f);
        int width = (int) (rectBox.width() / f);
        int height = (int) (rectBox.height() / f);

        if (left < 0) {
            left = 0;
        }
        if (top < 0) {
            top = 0;
        }

        if (left + width > bmp.getWidth()) {
            width = bmp.getWidth() - left;
        }
        if (top + height > bmp.getHeight()) {
            height = bmp.getHeight() - top;
        }

        int k = width;
        if (width < expectSize) {
            k = expectSize;
        }
        if (width > expectSize) {
            k = expectSize;
        }
        try {
            bmp = Bitmap.createBitmap(bmp, left, top, width, height);

            if (k != width && k != height) {//don't do this if equals
                bmp = Bitmap.createScaledBitmap(bmp, k, k, true);//scale the bitmap
            }

        } catch (OutOfMemoryError localOutOfMemoryError1) {
            Log.v(TAG, "OOM when create bitmap");
        }

        return bmp;
    }

    /**
     * create a file to save photo
     *
     * @param ctx
     * @return
     */
    private File createImageSaveFile(Context ctx) {
        if (Util.isStorageEnable()) {
            // 
            File pic = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
            if (!pic.exists()) {
                pic.mkdirs();
            }
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
            String fileName = "IMG_" + timeStamp;
            File tmpFile = new File(pic, fileName + ".jpg");
            mCurrentPhotoPath = tmpFile.getAbsolutePath();
            Log.i(TAG, "=====camera path:" + mCurrentPhotoPath);
            return tmpFile;
        } else {
            //File cacheDir = ctx.getCacheDir();
            File cacheDir = Environment.getDataDirectory();
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
            String fileName = "IMG_" + timeStamp;
            File tmpFile = new File(cacheDir, fileName + ".jpg");
            mCurrentPhotoPath = tmpFile.getAbsolutePath();
            Log.i(TAG, "=====camera path:" + mCurrentPhotoPath);
            return tmpFile;
        }
    }

    /**
     * take picture
     */
    public void takePicture(Context ctx, int requestCode) throws IOException {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(ctx.getPackageManager()) != null) {
            // Create the File where the photo should go
            //File photoFile = createImageFile();
            File photoFile = createImageSaveFile(ctx);
            // Continue only if the File was successfully created
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            }
        }
        if (ctx instanceof Activity) {
            ((Activity) ctx).startActivityForResult(takePictureIntent, requestCode);
        }

    }

    /**
     * take picture
     */
    public void takePicture(Fragment fragment, int requestCode) throws IOException {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //Intent takePictureIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
        takePictureIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(fragment.getActivity().getPackageManager()) != null) {
            // Create the File where the photo should go
            //File photoFile = createImageFile();
            File photoFile = createImageSaveFile(fragment.getActivity());
            // Continue only if the File was successfully created
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                Log.i(TAG, "=====file ready to take photo:" + photoFile.getAbsolutePath());
            }
        }
        fragment.startActivityForResult(takePictureIntent, requestCode);

    }

    /**
     * scan the photo so that the gallery can read it
     *
     * @param ctx
     * @param path
     */
    public static void galleryAddPic(Context ctx, String path) {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File f = new File(path);
        Uri contentUri = Uri.fromFile(f);
        mediaScanIntent.setData(contentUri);
        ctx.sendBroadcast(mediaScanIntent);
        Log.i(TAG, "=====MediaScan:" + path);
    }

    /**
     * listener for one Image Item selected observe
     */
    public interface OnImageSelectedListener {
        void onImageSelected(int position, ImageItem item, int selectedItemsCount, int maxSelectLimit);
    }

    public interface OnImageCropCompleteListener {
        void onImageCropComplete(Bitmap bmp, float ratio);
    }

    public interface OnPictureTakeCompleteListener {
        void onPictureTakeComplete(String picturePath);
    }

    public interface OnImagePickCompleteListener {
        void onImagePickComplete(List<ImageItem> items);
    }

    public interface OnImagePageSelectedListener {
        void onImagePageSelected(List<ImageItem> items);
    }

    public interface Select_Mode {
        int MODE_SINGLE = 0;
        int MODE_MULTI = 1;
    }

}