Last active
April 24, 2017 10:19
-
-
Save dseerapu/f4aa970ae746d2b522aa4482eee30092 to your computer and use it in GitHub Desktop.
Image Picker from Gallery and Photo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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