Android picture selection and calling system cropping

Not much to say, directly give a tool class, take what you want

 

package com.locinengine.utils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.view.ContextThemeWrapper;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.Toast;

/**
 * Photo selection
 *
 * @author [email protected]
 *
 */
public class PhotoPickUtil {
	private final int _2000 = 2000;
	private Activity activityContext;
	private Fragment fragmentContext;
	private OnPhotoPickedlistener onPhotoPickedlistener;

	public PhotoPickUtil(Activity context,
			OnPhotoPickedlistener onPhotoPickedlistener) {
		super();
		this.activityContext = context;
		this.onPhotoPickedlistener = onPhotoPickedlistener;
	}

	public PhotoPickUtil(Activity activityContext, Fragment fragmentContext,
			OnPhotoPickedlistener onPhotoPickedlistener) {
		super();
		this.activityContext = activityContext;
		this.fragmentContext = fragmentContext;
		this.onPhotoPickedlistener = onPhotoPickedlistener;
	}

/**
Call this method in onActivityResult(...) of the called activity or fragment to process the data returned by the photo/album
*/
	public void pickResult(int requestCode, int resultCode, Intent data) {
		if (resultCode != Activity.RESULT_OK)
			return;
		switch (requestCode) {
		case CROPED_PHOTO: // Called image cropping returned
			Bitmap img = data.getParcelableExtra("data");
			if (onPhotoPickedlistener != null) {
				onPhotoPickedlistener.photoPicked(null, img);
			}

			break;

		case CAMERA_WITH_DATA: // returned by the camera program
			if (doCrop) {
				doCropPhoto(mCurrentPhotoFile, cropWidth, cropHeight);
			} else {
				if (onPhotoPickedlistener != null) {
					onPhotoPickedlistener.photoPicked(
							mCurrentPhotoFile.getPath (), null);
					mCurrentPhotoFile = null;
				}
			}
			break;
		case PHOTO_PICKED:
			Uri originalUri = data.getData(); // Call the album to select the returned picture

			String path = getGalleryImgPath(originalUri);
			if (doCrop) {
				doCropPhoto(new File(path), cropWidth, cropHeight);
			} else {
				if (onPhotoPickedlistener != null) {
					onPhotoPickedlistener.photoPicked(path, null);
				}
			}
			break;
		}
	}

	private boolean doCrop;
	private int cropWidth;
	private int cropHeight;
	/*
	 * Used to identify the activity requesting the camera function
	 */
	public final int CAMERA_WITH_DATA = 3023;
	/*
	 * Used to identify the activity requesting the gallery
	 */
	public final int CAMERA_CROP = 3022;
	/*
	 * Used to identify the activity requesting the gallery
	 */
	public final int CROPED_PHOTO = 3021;
	public final int PHOTO_PICKED = 3024;
	/*
	 * The storage location of the photo taken
	 */
	private final File PHOTO_DIR_SD = new File(
			Environment.getExternalStorageDirectory() + "/DCIM/Camera");
	private final File PHOTO_DIR_ROOT = new File(Environment.getRootDirectory()
			+ "/DCIM/Camera");
	private File mCurrentPhotoFile;// The picture taken by the camera

	/**
	 * There are 3 options for deselecting pictures (you need to set up a listener), taking pictures and selecting pictures
	 *
	 * @param activity
	 * @param cropImg
	 * @param outWith
	 * @param outHeight
	 * @param cancelClickListener
	 */
	public void doPickPhotoAction(final boolean cropImg, final int outWith,
			final int outHeight,
			final OnPickPhotoCancelClickListener cancelClickListener) {
		this.doCrop = cropImg;
		this.cropWidth = outWith;
		this.cropHeight = outHeight;
		File dir = null;
		// showToast(activity, "If adding a real-time photo will cause a restart, please try to take a photo outside the app, and then choose to add it from the album!");
		String status = Environment.getExternalStorageState();
		if (status.equals(Environment.MEDIA_MOUNTED)) {// Determine whether there is an SD card
			dir = PHOTO_DIR_SD;
		} else {
			dir = PHOTO_DIR_ROOT;
		}
		if (!dir.exists()) {
			dir.mkdirs();//Create a storage directory for photos
		}
		mCurrentPhotoFile = new File(dir, getImgName());// Name the photo file of the new photo
		// Wrap our context to inflate list items using correct theme
		Context dialogContext = new ContextThemeWrapper(activityContext,
				android.R.style.Theme_Light);
		String cancel = "return";
		String[] choices = new String[3];
		choices[0] = "Clear";//
		choices[1] = "Photo";// getString(MediaStore.ACTION_IMAGE_CAPTURE); //Take a photo
		choices[2] = "Select a picture from the album";// getString(R.string.pick_photo); //Select from the album
		ListAdapter adapter = new ArrayAdapter<String>(dialogContext,
				android.R.layout.simple_list_item_1, choices);

		AlertDialog.Builder builder = new AlertDialog.Builder(dialogContext);
		builder.setTitle("Select picture");
		builder.setSingleChoiceItems(adapter, -1,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						switch (which) {
						case 0:
							if (cancelClickListener != null) {
								cancelClickListener.onClick();
							}
							dialog.dismiss();
							break;
						case 1: {
							doTakePhoto();
							break;

						}
						case 2:
							doPickPhotoFromGallery();// Get it from the album
							break;
						}
					}
				});
		builder.setNegativeButton(cancel,
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}

				});
		builder.create().show();
	}

	/**
	 * There are only two options to take a photo and select a photo
	 *
	 * @param activity
	 * @param cropImg
	 * @param outWith
	 * @param outHeight
	 */
	public void doPickPhotoAction(final boolean cropImg, final int outWith,
			final int outHeight) {
		this.doCrop = cropImg;
		this.cropWidth = outWith;
		this.cropHeight = outHeight;
		File dir = null;
		// showToast(activity, "If adding a real-time photo will cause a restart, please try to take a photo outside the app, and then choose to add it from the album!");
		String status = Environment.getExternalStorageState();
		if (status.equals(Environment.MEDIA_MOUNTED)) {// Determine whether there is an SD card
			dir = PHOTO_DIR_SD;
		} else {
			dir = PHOTO_DIR_ROOT;
		}
		if (!dir.exists()) {
			dir.mkdirs();//Create a storage directory for photos
		}
		mCurrentPhotoFile = new File(dir, getImgName());// Name the photo file of the new photo

		// Wrap our context to inflate list items using correct theme
		Context dialogContext = new ContextThemeWrapper(activityContext,
				android.R.style.Theme_Light);
		String cancel = "return";
		String[] choices = new String[2];
		choices[0] = "Photo";// getString(MediaStore.ACTION_IMAGE_CAPTURE); //Take a photo
		choices[1] = "Select a picture from the album";// getString(R.string.pick_photo); //Select from the album
		ListAdapter adapter = new ArrayAdapter<String>(dialogContext,
				android.R.layout.simple_list_item_1, choices);

		AlertDialog.Builder builder = new AlertDialog.Builder(dialogContext);
		builder.setTitle("Select picture");
		builder.setSingleChoiceItems(adapter, -1,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						switch (which) {
						case 0: {
							doTakePhoto();
							break;

						}
						case 1:
							doPickPhotoFromGallery();// Get it from the album
							break;
						}
					}
				});
		builder.setNegativeButton(cancel,
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}

				});
		builder.create().show();
	}

	/**
	 * Take pictures to get pictures
	 *
	 * @param cropImg
	 *
	 */
	private void doTakePhoto() {
		try {
			final Intent intent = getTakePickIntent(mCurrentPhotoFile);
			if (fragmentContext != null)
				fragmentContext
						.startActivityForResult(intent, CAMERA_WITH_DATA);
			else
				activityContext
						.startActivityForResult(intent, CAMERA_WITH_DATA);
		} catch (ActivityNotFoundException e) {
			e.printStackTrace ();
			Toast.makeText(activityContext, "Failed to get picture", _2000).show();
		}
	}

	private Intent getTakePickIntent(File f) {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, null);
		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
		if (doCrop) {
			intent.putExtra("return-data", true);
		}
		return intent;
	}

	// Request the Gallery program
	private void doPickPhotoFromGallery() {
		try {
			// Launch picker to choose photo for selected contact
			final Intent intent = getPhotoPickIntent();
			if (fragmentContext != null)
				fragmentContext.startActivityForResult(intent, PHOTO_PICKED);
			else
				activityContext.startActivityForResult(intent, PHOTO_PICKED);
		} catch (ActivityNotFoundException e) {
			e.printStackTrace ();
			Toast.makeText(activityContext, "Failed to get picture", _2000).show();
		}
	}

	// Encapsulate the intent of requesting Gallery
	private Intent getPhotoPickIntent() {
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
		intent.setType("image/*");
		// if (cropImg) {
		// intent.putExtra("crop", "true");
		// // Set the cropping frame aspect ratio and output image size, not the original size
		// // if (outHeight > outWith) {
		// // intent.putExtra("aspectX", 1);
		// // intent.putExtra("aspectY", outHeight / outWith);
		// // } else if (outWith > outHeight) {
		// intent.putExtra("aspectX", outWith);
		// intent.putExtra("aspectY", outHeight);
		// // }
		// intent.putExtra("outputX", outWith);
		// intent.putExtra("outputY", outHeight);
		// // Set the system to return the image bitmap object
		// intent.putExtra("return-data", true);
		// }
		return intent;
	}

	private void doCropPhoto(File f, int outWith, int outHeight) {
		try {
			// start gallery to edit this photo
			final Intent intent = getCropImageIntent(Uri.fromFile(f), outWith,
					outHeight);
			if (fragmentContext != null)
				fragmentContext.startActivityForResult(intent, CROPED_PHOTO);
			else
				activityContext.startActivityForResult(intent, CROPED_PHOTO);
		} catch (Exception e) {
			Toast.makeText(activityContext, "Failed to get picture", _2000).show();
		}
	}

	/**
	 * Constructs an intent for image cropping. Call the image cropping program
	 */
	private Intent getCropImageIntent(Uri photoUri, int outWith, int outHeight) {
		Intent intent = new Intent("com.android.camera.action.CROP")
				.setDataAndType(photoUri, "image/*").putExtra("crop", "true")
				.putExtra("return-data", true);
		// .putExtra("scale", true)
		// // Black border
		// .putExtra("scaleUpIfNeeded", true)
		// // Black border
		intent.putExtra("aspectX", outWith);
		intent.putExtra("aspectY", outHeight);
		intent.putExtra("outputX", outWith);
		intent.putExtra("outputY", outHeight);
		return intent;
	}

	@SuppressWarnings("deprecation")
	private String getGalleryImgPath(Uri photoUri) {
		// The second part starting here, get the path of the image:

		String[] proj = { MediaStore.Images.Media.DATA };

		// It seems to be the encapsulation interface of the android multimedia database, see the Android documentation for details
		Cursor cursor = activityContext.managedQuery(photoUri, proj, null,
				null, null);

		// According to my personal understanding, this is to get the index value of the picture selected by the user
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

		// Move the cursor to the beginning, this is very important, it is easy to cross the border accidentally
		cursor.moveToFirst();

		// Finally get the image path according to the index value
		String path = cursor.getString(column_index);

		return path;
	}

	@SuppressLint("SimpleDateFormat")
	private String getImgName() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern("yyyyMMdd_HHmmsss");
		StringBuilder result = new StringBuilder("IMG_");
		result.append(sdf.format(new Date()) + (int) (Math.random() * 100))
				.append(".jpg");
		return result.toString();
	}

	public interface OnPhotoPickedlistener {

		public void photoPicked(String path, Bitmap bmp);
	}

	public interface OnPickPhotoCancelClickListener {

		public void onClick();
	}
}

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327061044&siteId=291194637
Recommended