Skip to content

Commit

Permalink
Merge pull request #31 from dilix/dev/gallerypath/0
Browse files Browse the repository at this point in the history
Several new methods to support many pictures per screen.
  • Loading branch information
Mariovc authored Jul 6, 2017
2 parents 3d5c15a + 206690d commit ddfb903
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 43 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ ext {
configuration = [
app_name : "ImagePicker",
packageName : "com.mvc.imagepicker",
compileVersion : 24,
buildToolsVersion : "23.0.3",
compileVersion : 25,
buildToolsVersion : "25.0.3",
minSdk : 14,
targetSdk : 24
]
Expand All @@ -36,7 +36,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
classpath 'com.android.tools.build:gradle:2.3.3'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Thu Sep 08 12:02:41 CEST 2016
#Fri Jun 30 14:03:37 MSK 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
206 changes: 175 additions & 31 deletions library/src/main/java/com/mvc/imagepicker/ImagePicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import android.net.Uri;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
Expand All @@ -49,7 +50,8 @@
*/
public final class ImagePicker {

public static final int PICK_IMAGE_REQUEST_CODE = 234; // the number doesn't matter
private static final int DEFAULT_REQUEST_CODE = 234;

private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; // min pixels
private static final int DEFAULT_MIN_HEIGHT_QUALITY = 400; // min pixels
private static final String TAG = ImagePicker.class.getSimpleName();
Expand All @@ -58,29 +60,71 @@ public final class ImagePicker {
private static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY;
private static int minHeightQuality = DEFAULT_MIN_HEIGHT_QUALITY;

private static String mChooserTitle;
private static int mPickImageRequestCode = DEFAULT_REQUEST_CODE;
private static boolean mGalleryOnly = false;

private ImagePicker() {
// not called
}

/**
* Launch a dialog to pick an image from camera/gallery apps.
* Launch a dialog to pick an image from camera/gallery apps with custom request code.
*
* @param activity which will launch the dialog.
* @param requestCode request code that will be returned in result.
*/
public static void pickImage(Activity activity, int requestCode) {
pickImage(activity, activity.getString(R.string.pick_image_intent_text), requestCode, false);
}

/**
* Launch a dialog to pick an image from camera/gallery apps with custom request code.
*
* @param activity which will launch the dialog.
*/
public static void pickImage(Activity activity) {
String chooserTitle = activity.getString(R.string.pick_image_intent_text);
pickImage(activity, chooserTitle);
pickImage(activity, activity.getString(R.string.pick_image_intent_text), DEFAULT_REQUEST_CODE, false);
}

/**
* Launch a dialog to pick an image from camera/gallery apps.
* Launch a dialog to pick an image from camera/gallery apps with custom request code.
*
* @param fragment which will launch the dialog and will get the result in
* onActivityResult()
* @param fragment which will launch the dialog.
* @param requestCode request code that will be returned in result.
*/
public static void pickImage(Fragment fragment, int requestCode) {
pickImage(fragment, fragment.getString(R.string.pick_image_intent_text), requestCode, false);
}

/**
* Launch a dialog to pick an image from camera/gallery apps with custom request code.
*
* @param fragment which will launch the dialog.
*/
public static void pickImage(Fragment fragment) {
String chooserTitle = fragment.getString(R.string.pick_image_intent_text);
pickImage(fragment, chooserTitle);
pickImage(fragment, fragment.getString(R.string.pick_image_intent_text), DEFAULT_REQUEST_CODE, false);
}

/**
* Launch a dialog to pick an image from gallery apps only with custom request code.
*
* @param activity which will launch the dialog.
* @param requestCode request code that will be returned in result.
*/
public static void pickImageGalleryOnly(Activity activity, int requestCode) {
pickImage(activity, activity.getString(R.string.pick_image_intent_text), requestCode, true);

}

/**
* Launch a dialog to pick an image from gallery apps only with custom request code.
*
* @param fragment which will launch the dialog.
* @param requestCode request code that will be returned in result.
*/
public static void pickImageGalleryOnly(Fragment fragment, int requestCode) {
pickImage(fragment, fragment.getString(R.string.pick_image_intent_text), requestCode, true);
}

/**
Expand All @@ -90,8 +134,7 @@ public static void pickImage(Fragment fragment) {
* @param chooserTitle will appear on the picker dialog.
*/
public static void pickImage(Activity activity, String chooserTitle) {
Intent chooseImageIntent = getPickImageIntent(activity, chooserTitle);
activity.startActivityForResult(chooseImageIntent, PICK_IMAGE_REQUEST_CODE);
pickImage(activity, chooserTitle, DEFAULT_REQUEST_CODE, false);
}

/**
Expand All @@ -102,8 +145,48 @@ public static void pickImage(Activity activity, String chooserTitle) {
* @param chooserTitle will appear on the picker dialog.
*/
public static void pickImage(Fragment fragment, String chooserTitle) {
Intent chooseImageIntent = getPickImageIntent(fragment.getContext(), chooserTitle);
fragment.startActivityForResult(chooseImageIntent, PICK_IMAGE_REQUEST_CODE);
pickImage(fragment, chooserTitle, DEFAULT_REQUEST_CODE, false);
}

/**
* Launch a dialog to pick an image from camera/gallery apps.
*
* @param fragment which will launch the dialog and will get the result in
* onActivityResult()
* @param chooserTitle will appear on the picker dialog.
* @param requestCode request code that will be returned in result.
*/
public static void pickImage(Fragment fragment, String chooserTitle,
int requestCode, boolean galleryOnly) {
mGalleryOnly = galleryOnly;
mPickImageRequestCode = requestCode;
mChooserTitle = chooserTitle;
startChooser(fragment);
}

/**
* Launch a dialog to pick an image from camera/gallery apps.
*
* @param activity which will launch the dialog and will get the result in
* onActivityResult()
* @param chooserTitle will appear on the picker dialog.
*/
public static void pickImage(Activity activity, String chooserTitle,
int requestCode, boolean galleryOnly) {
mGalleryOnly = galleryOnly;
mPickImageRequestCode = requestCode;
mChooserTitle = chooserTitle;
startChooser(activity);
}

private static void startChooser(Fragment fragmentContext) {
Intent chooseImageIntent = getPickImageIntent(fragmentContext.getContext(), mChooserTitle);
fragmentContext.startActivityForResult(chooseImageIntent, mPickImageRequestCode);
}

private static void startChooser(Activity activityContext) {
Intent chooseImageIntent = getPickImageIntent(activityContext, mChooserTitle);
activityContext.startActivityForResult(chooseImageIntent, mPickImageRequestCode);
}

/**
Expand All @@ -121,16 +204,20 @@ public static Intent getPickImageIntent(Context context, String chooserTitle) {
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intentList = addIntentsToList(context, intentList, pickIntent);

// Camera action will fail if the app does not have permission, check before adding intent.
// We only need to add the camera intent if the app does not use the CAMERA permission
// in the androidmanifest.xml
// Or if the user has granted access to the camera.
// See https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
if (!appManifestContainsPermission(context, Manifest.permission.CAMERA) || hasCameraAccess(context)) {
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTemporalFile(context)));
intentList = addIntentsToList(context, intentList, takePhotoIntent);
// Check is we want gallery apps only
if (!mGalleryOnly) {
// Camera action will fail if the app does not have permission, check before adding intent.
// We only need to add the camera intent if the app does not use the CAMERA permission
// in the androidmanifest.xml
// Or if the user has granted access to the camera.
// See https://developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE
if (!appManifestContainsPermission(context, Manifest.permission.CAMERA) || hasCameraAccess(context)) {
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(ImageUtils.getTemporalFile(context, String.valueOf(mPickImageRequestCode))));
intentList = addIntentsToList(context, intentList, takePhotoIntent);
}
}

if (intentList.size() > 0) {
Expand Down Expand Up @@ -202,12 +289,13 @@ private static boolean appManifestContainsPermission(Context context, String per
* @param imageReturnedIntent returned intent where is the image data.
* @return image.
*/
@Nullable
public static Bitmap getImageFromResult(Context context, int requestCode, int resultCode,
Intent imageReturnedIntent) {
Log.i(TAG, "getImageFromResult() called with: " + "resultCode = [" + resultCode + "]");
Bitmap bm = null;
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST_CODE) {
File imageFile = getTemporalFile(context);
if (resultCode == Activity.RESULT_OK && requestCode == mPickImageRequestCode) {
File imageFile = ImageUtils.getTemporalFile(context, String.valueOf(mPickImageRequestCode));
Uri selectedImage;
boolean isCamera = (imageReturnedIntent == null
|| imageReturnedIntent.getData() == null
Expand All @@ -226,6 +314,66 @@ public static Bitmap getImageFromResult(Context context, int requestCode, int re
return bm;
}

/**
* Called after launching the picker with the same values of Activity.getImageFromResult
* in order to resolve the result and get the image path.
*
* @param context context.
* @param requestCode used to identify the pick image action.
* @param resultCode -1 means the result is OK.
* @param imageReturnedIntent returned intent where is the image data.
* @return path to the saved image.
*/
@Nullable
public static String getImagePathFromResult(Context context, int requestCode, int resultCode,
Intent imageReturnedIntent) {
Log.i(TAG, "getImagePathFromResult() called with: " + "resultCode = [" + resultCode + "]");
Uri selectedImage = null;
if (resultCode == Activity.RESULT_OK && requestCode == mPickImageRequestCode) {
File imageFile = ImageUtils.getTemporalFile(context, String.valueOf(mPickImageRequestCode));
boolean isCamera = (imageReturnedIntent == null
|| imageReturnedIntent.getData() == null
|| imageReturnedIntent.getData().toString().contains(imageFile.toString()));
if (isCamera) {
return imageFile.getAbsolutePath();
} else {
selectedImage = imageReturnedIntent.getData();
}
Log.i(TAG, "selectedImage: " + selectedImage);
}
if (selectedImage == null) {
return null;
}
return getFilePathFromUri(context, selectedImage);
}

/**
* Get stream, save the picture to the temp file and return path.
*
* @param context context
* @param uri uri of the incoming file
* @return path to the saved image.
*/
private static String getFilePathFromUri(Context context, Uri uri) {
InputStream is = null;
if (uri.getAuthority() != null) {
try {
is = context.getContentResolver().openInputStream(uri);
Bitmap bmp = BitmapFactory.decodeStream(is);
return ImageUtils.savePicture(context, bmp, String.valueOf(uri.getPath().hashCode()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}

/**
* Called after launching the picker with the same values of Activity.getImageFromResult
* in order to resolve the result and get the input stream for the image.
Expand All @@ -239,8 +387,8 @@ public static Bitmap getImageFromResult(Context context, int requestCode, int re
public static InputStream getInputStreamFromResult(Context context, int requestCode, int resultCode,
Intent imageReturnedIntent) {
Log.i(TAG, "getFileFromResult() called with: " + "resultCode = [" + resultCode + "]");
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST_CODE) {
File imageFile = getTemporalFile(context);
if (resultCode == Activity.RESULT_OK && requestCode == mPickImageRequestCode) {
File imageFile = ImageUtils.getTemporalFile(context, String.valueOf(mPickImageRequestCode));
Uri selectedImage;
boolean isCamera = (imageReturnedIntent == null
|| imageReturnedIntent.getData() == null
Expand Down Expand Up @@ -268,10 +416,6 @@ public static InputStream getInputStreamFromResult(Context context, int requestC
return null;
}

private static File getTemporalFile(Context context) {
return new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
}

/**
* Loads a bitmap and avoids using too much memory loading big images (e.g.: 2560*1920)
*/
Expand Down
51 changes: 51 additions & 0 deletions library/src/main/java/com/mvc/imagepicker/ImageUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.mvc.imagepicker;

import android.content.Context;
import android.graphics.Bitmap;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
* Created by Anatol on 11/12/2016.
*/

public final class ImageUtils {

private static final String BASE_IMAGE_NAME = "i_prefix_";

private ImageUtils() {
}

public static String savePicture(Context context, Bitmap bitmap, String imageSuffix) {
File savedImage = getTemporalFile(context, imageSuffix + ".jpeg");
FileOutputStream fos = null;
if (savedImage.exists()) {
savedImage.delete();
}
try {
fos = new FileOutputStream(savedImage.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
} catch (java.io.IOException e) {
e.printStackTrace();
} finally {
if (!bitmap.isRecycled()) {
bitmap.recycle();
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

return savedImage.getAbsolutePath();
}

public static File getTemporalFile(Context context, String payload) {
return new File(context.getExternalCacheDir(), BASE_IMAGE_NAME + payload);
}
}
2 changes: 2 additions & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ android {
}
}
}
buildToolsVersion '25.0.0'
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.squareup.picasso:picasso:2.5.2'
compile "com.android.support:appcompat-v7:${libs.supportVersion}"
compile project(':library')
}
Loading

0 comments on commit ddfb903

Please sign in to comment.