Skip to content

Instantly share code, notes, and snippets.

@dseerapu
Last active April 24, 2017 10:19
Show Gist options
  • Save dseerapu/f4aa970ae746d2b522aa4482eee30092 to your computer and use it in GitHub Desktop.
Save dseerapu/f4aa970ae746d2b522aa4482eee30092 to your computer and use it in GitHub Desktop.
Image Picker from Gallery and Photo
package com.bolste.android.activities.ui.utils;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.content.FileProvider;
import android.util.Log;
import com.bolste.android.settings.BolsterEditProfileActivity;
import java.io.File;
import java.io.IOException;
public class ImageInputHelper {
public static final int REQUEST_PICTURE_FROM_GALLERY = 23;
public static final int REQUEST_PICTURE_FROM_CAMERA = 24;
public static final int REQUEST_CROP_PICTURE = 25;
private static final String TAG = "ImageInputHelper";
private File tempFileFromSource = null;
private Uri tempUriFromSource = null;
private File tempFileFromCrop = null;
private Uri tempUriFromCrop = null;
/**
* Activity object that will be used while calling startActivityForResult(). Activity then will
* receive the callbacks to its own onActivityResult() and is responsible of calling the
* onActivityResult() of the ImageInputHelper for handling result and being notified.
*/
private Activity mContext;
/**
* Fragment object that will be used while calling startActivityForResult(). Fragment then will
* receive the callbacks to its own onActivityResult() and is responsible of calling the
* onActivityResult() of the ImageInputHelper for handling result and being notified.
*/
private Fragment fragment;
/**
* Listener instance for callbacks on user events. It must be set to be able to use
* the ImageInputHelper object.
*/
private ImageActionListener imageActionListener;
public ImageInputHelper(Activity mContext) {
this.mContext = mContext;
}
public ImageInputHelper(Fragment fragment) {
this.fragment = fragment;
this.mContext = fragment.getActivity();
}
public void setImageActionListener(ImageActionListener imageActionListener) {
this.imageActionListener = imageActionListener;
}
/**
* Handles the result of events that the Activity or Fragment receives on its own
* onActivityResult(). This method must be called inside the onActivityResult()
* of the container Activity or Fragment.
*
* @param requestCode
* @param resultCode
* @param data
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if ((requestCode == REQUEST_PICTURE_FROM_GALLERY) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from gallery");
imageActionListener.onImageSelectedFromGallery(data.getData(), tempFileFromSource);
} else if ((requestCode == REQUEST_PICTURE_FROM_CAMERA) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image selected from camera");
imageActionListener.onImageTakenFromCamera(tempUriFromSource, tempFileFromSource);
} else if ((requestCode == REQUEST_CROP_PICTURE) && (resultCode == Activity.RESULT_OK)) {
Log.d(TAG, "Image returned from crop");
imageActionListener.onImageCropped(tempUriFromCrop, tempFileFromCrop);
}
}
/**
* Starts an intent for selecting image from gallery. The result is returned to the
* onImageSelectedFromGallery() method of the ImageSelectionListener interface.
*
* @param bolsterEditProfileActivity
*/
public void selectImageFromGallery(BolsterEditProfileActivity bolsterEditProfileActivity) {
checkListener();
if (tempFileFromSource == null) {
try {
tempFileFromSource = File.createTempFile("choose", "png", mContext.getExternalCacheDir());
// tempUriFromSource = Uri.fromFile(tempFileFromSource);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
tempUriFromSource = FileProvider.getUriForFile(bolsterEditProfileActivity,
bolsterEditProfileActivity.getApplicationContext()
.getPackageName() + ".provider", tempFileFromSource);
} else {
tempUriFromSource = Uri.fromFile(tempFileFromSource);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
if (fragment == null) {
mContext.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
} else {
fragment.startActivityForResult(intent, REQUEST_PICTURE_FROM_GALLERY);
}
}
/**
* Starts an intent for taking photo with camera. The result is returned to the
* onImageTakenFromCamera() method of the ImageSelectionListener interface.
*
* @param bolsterEditProfileActivity
*/
public void takePhotoWithCamera(BolsterEditProfileActivity bolsterEditProfileActivity) {
checkListener();
if (tempFileFromSource == null) {
try {
tempFileFromSource = File.createTempFile("choose", "png", mContext.getExternalCacheDir());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
tempUriFromSource = FileProvider.getUriForFile(bolsterEditProfileActivity,
bolsterEditProfileActivity.getApplicationContext()
.getPackageName() + ".provider", tempFileFromSource);
} else {
tempUriFromSource = Uri.fromFile(tempFileFromSource);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, tempUriFromSource);
if (fragment == null) {
try {
mContext.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
} catch (Exception e) {
Log.e(TAG, "" + e);
}
} else {
fragment.startActivityForResult(intent, REQUEST_PICTURE_FROM_CAMERA);
}
}
/**
* Starts an intent for cropping an image that is saved in the uri. The result is
* returned to the onImageCropped() method of the ImageSelectionListener interface.
*
* @param uri uri that contains the data of the image to crop
* @param outputX width of the result image
* @param outputY height of the result image
* @param aspectX horizontal ratio value while cutting the image
* @param aspectY vertical ratio value of while cutting the image
*/
public void requestCropImage(Uri uri, int outputX, int outputY, int aspectX, int aspectY) {
checkListener();
if (tempFileFromCrop == null) {
try {
tempFileFromCrop = File.createTempFile("crop", "png", mContext.getExternalCacheDir());
tempUriFromCrop = Uri.fromFile(tempFileFromCrop);
} catch (IOException e) {
e.printStackTrace();
}
}
// open crop intent when user selects image
final Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("output", tempUriFromCrop);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("scale", true);
intent.putExtra("noFaceDetection", true);
if (fragment == null) {
mContext.startActivityForResult(intent, REQUEST_CROP_PICTURE);
} else {
fragment.startActivityForResult(intent, REQUEST_CROP_PICTURE);
}
}
private void checkListener() {
if (imageActionListener == null) {
throw new RuntimeException("ImageSelectionListener must be set before calling openGalleryIntent(), openCameraIntent() or requestCropImage().");
}
}
/**
* Listener interface for receiving callbacks from the ImageInputHelper.
*/
public interface ImageActionListener {
void onImageSelectedFromGallery(Uri uri, File imageFile);
void onImageTakenFromCamera(Uri uri, File imageFile);
void onImageCropped(Uri uri, File imageFile);
}
}
Use above Class using below:
public class ProfileActivity extends AppCompatActivity implements ImageInputHelper.ImageActionListener {
private static final int REQUEST_CAMERA = 0;
private static final int SELECT_FILE = 1;
private String userChoosenTask;
@BindString(R.string.profile_update_image_not_completed)
protected String profileImageUpdateIsNotYetCompleted;
@BindString(R.string.unable_to_change_profile_picture)
protected String unableToChangeProfilePicture;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageInputHelper = new ImageInputHelper(this);
imageInputHelper.setImageActionListener(this);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == Utility.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (userChoosenTask.equals(takePhoto))
cameraIntent();
else if (userChoosenTask.equals(chooseFromLibrary))
galleryIntent();
} else {
//code for deny
}
} else if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
//do nothing
}
}
@OnClick(R.id.txt_edit_avatar_url)
protected void changeImage() {
// Toast.makeText(this, "Work in progress", Toast.LENGTH_SHORT).show();
selectImage();
}
private void selectImage() {
final CharSequence[] items = {takePhoto, chooseFromLibrary, resetToDefaultAvatar, cancel};
AlertDialog.Builder builder = new AlertDialog.Builder(BolsterEditProfileActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals(takePhoto)) {
boolean result = isResult();
userChoosenTask = takePhoto;
if (result)
cameraIntent();
} else if (items[item].equals(chooseFromLibrary)) {
boolean result = isResult();
userChoosenTask = chooseFromLibrary;
if (result)
galleryIntent();
} else if (items[item].equals(cancel)) {
dialog.dismiss();
}
}
});
builder.show();
}
private boolean isResult() {
return Utility.checkPermission(BolsterEditProfileActivity.this);
}
private void galleryIntent() {
imageInputHelper.selectImageFromGallery(this);
}
private void cameraIntent() {
imageInputHelper.takePhotoWithCamera(this);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
imageInputHelper.onActivityResult(requestCode, resultCode, data);
}
private void changeProfileImage(File thumbnail, final Uri uri, final Bitmap bitmap) {
LoadImageUtils.loadImage(selfDetails.getAvatarUrl(), this, personImage);
}
@Override
public void onImageSelectedFromGallery(Uri uri, File imageFile) {
// cropping the selected image. crop intent will have aspect ratio 16/9 and result image
// will have size 800x450
imageInputHelper.requestCropImage(uri, width, 450, 3, 3);
}
@Override
public void onImageTakenFromCamera(Uri uri, File imageFile) {
// cropping the taken photo. crop intent will have aspect ratio 16/9 and result image
// will have size 800x450
imageInputHelper.requestCropImage(uri, 450, 450, 3, 3);
}
@Override
public void onImageCropped(Uri uri, File imageFile) {
try {
// getting bitmap from uri
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
// showing bitmap in image view
// personImage.setImageBitmap(bitmap);
showProgressDialog(this);
changeProfileImage(imageFile, uri, bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
Marshmallow permission utility Class :
public class Utility {
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
private Utility(){
//do nothing
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkPermission(final Context context) {
int currentAPIVersion = Build.VERSION.SDK_INT;
if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("External storage permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment