-
Star
(160)
You must be signed in to star a gist -
Fork
(51)
You must be signed in to fork a gist
-
-
Save Mariovc/f06e70ebe8ca52fbbbe2 to your computer and use it in GitHub Desktop.
| import android.app.Activity; | |
| import android.content.Context; | |
| import android.content.Intent; | |
| import android.content.pm.ResolveInfo; | |
| import android.content.res.AssetFileDescriptor; | |
| import android.database.Cursor; | |
| import android.graphics.Bitmap; | |
| import android.graphics.BitmapFactory; | |
| import android.graphics.Matrix; | |
| import android.media.ExifInterface; | |
| import android.net.Uri; | |
| import android.os.Parcelable; | |
| import android.provider.MediaStore; | |
| import android.util.Log; | |
| import java.io.File; | |
| import java.io.FileNotFoundException; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| /** | |
| * Author: Mario Velasco Casquero | |
| * Date: 08/09/2015 | |
| * Email: [email protected] | |
| */ | |
| public class ImagePicker { | |
| private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; // min pixels | |
| private static final String TAG = "ImagePicker"; | |
| private static final String TEMP_IMAGE_NAME = "tempImage"; | |
| public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY; | |
| public static Intent getPickImageIntent(Context context) { | |
| Intent chooserIntent = null; | |
| List<Intent> intentList = new ArrayList<>(); | |
| Intent pickIntent = new Intent(Intent.ACTION_PICK, | |
| android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); | |
| Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | |
| takePhotoIntent.putExtra("return-data", true); | |
| takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context))); | |
| intentList = addIntentsToList(context, intentList, pickIntent); | |
| intentList = addIntentsToList(context, intentList, takePhotoIntent); | |
| if (intentList.size() > 0) { | |
| chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1), | |
| context.getString(R.string.pick_image_intent_text)); | |
| chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{})); | |
| } | |
| return chooserIntent; | |
| } | |
| private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) { | |
| List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0); | |
| for (ResolveInfo resolveInfo : resInfo) { | |
| String packageName = resolveInfo.activityInfo.packageName; | |
| Intent targetedIntent = new Intent(intent); | |
| targetedIntent.setPackage(packageName); | |
| list.add(targetedIntent); | |
| Log.d(TAG, "Intent: " + intent.getAction() + " package: " + packageName); | |
| } | |
| return list; | |
| } | |
| public static Bitmap getImageFromResult(Context context, int resultCode, | |
| Intent imageReturnedIntent) { | |
| Log.d(TAG, "getImageFromResult, resultCode: " + resultCode); | |
| Bitmap bm = null; | |
| File imageFile = getTempFile(context); | |
| if (resultCode == Activity.RESULT_OK) { | |
| Uri selectedImage; | |
| boolean isCamera = (imageReturnedIntent == null || | |
| imageReturnedIntent.getData() == null || | |
| imageReturnedIntent.getData().toString().contains(imageFile.toString())); | |
| if (isCamera) { /** CAMERA **/ | |
| selectedImage = Uri.fromFile(imageFile); | |
| } else { /** ALBUM **/ | |
| selectedImage = imageReturnedIntent.getData(); | |
| } | |
| Log.d(TAG, "selectedImage: " + selectedImage); | |
| bm = getImageResized(context, selectedImage); | |
| int rotation = getRotation(context, selectedImage, isCamera); | |
| bm = rotate(bm, rotation); | |
| } | |
| return bm; | |
| } | |
| private static File getTempFile(Context context) { | |
| File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME); | |
| imageFile.getParentFile().mkdirs(); | |
| return imageFile; | |
| } | |
| private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) { | |
| BitmapFactory.Options options = new BitmapFactory.Options(); | |
| options.inSampleSize = sampleSize; | |
| AssetFileDescriptor fileDescriptor = null; | |
| try { | |
| fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r"); | |
| } catch (FileNotFoundException e) { | |
| e.printStackTrace(); | |
| } | |
| Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor( | |
| fileDescriptor.getFileDescriptor(), null, options); | |
| Log.d(TAG, options.inSampleSize + " sample method bitmap ... " + | |
| actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight()); | |
| return actuallyUsableBitmap; | |
| } | |
| /** | |
| * Resize to avoid using too much memory loading big images (e.g.: 2560*1920) | |
| **/ | |
| private static Bitmap getImageResized(Context context, Uri selectedImage) { | |
| Bitmap bm = null; | |
| int[] sampleSizes = new int[]{5, 3, 2, 1}; | |
| int i = 0; | |
| do { | |
| bm = decodeBitmap(context, selectedImage, sampleSizes[i]); | |
| Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth()); | |
| i++; | |
| } while (bm.getWidth() < minWidthQuality && i < sampleSizes.length); | |
| return bm; | |
| } | |
| private static int getRotation(Context context, Uri imageUri, boolean isCamera) { | |
| int rotation; | |
| if (isCamera) { | |
| rotation = getRotationFromCamera(context, imageUri); | |
| } else { | |
| rotation = getRotationFromGallery(context, imageUri); | |
| } | |
| Log.d(TAG, "Image rotation: " + rotation); | |
| return rotation; | |
| } | |
| private static int getRotationFromCamera(Context context, Uri imageFile) { | |
| int rotate = 0; | |
| try { | |
| context.getContentResolver().notifyChange(imageFile, null); | |
| ExifInterface exif = new ExifInterface(imageFile.getPath()); | |
| int orientation = exif.getAttributeInt( | |
| ExifInterface.TAG_ORIENTATION, | |
| ExifInterface.ORIENTATION_NORMAL); | |
| switch (orientation) { | |
| case ExifInterface.ORIENTATION_ROTATE_270: | |
| rotate = 270; | |
| break; | |
| case ExifInterface.ORIENTATION_ROTATE_180: | |
| rotate = 180; | |
| break; | |
| case ExifInterface.ORIENTATION_ROTATE_90: | |
| rotate = 90; | |
| break; | |
| } | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| return rotate; | |
| } | |
| public static int getRotationFromGallery(Context context, Uri imageUri) { | |
| int result = 0; | |
| String[] columns = {MediaStore.Images.Media.ORIENTATION}; | |
| Cursor cursor = null; | |
| try { | |
| cursor = context.getContentResolver().query(imageUri, columns, null, null, null); | |
| if (cursor != null && cursor.moveToFirst()) { | |
| int orientationColumnIndex = cursor.getColumnIndex(columns[0]); | |
| result = cursor.getInt(orientationColumnIndex); | |
| } | |
| } catch (Exception e) { | |
| //Do nothing | |
| } finally { | |
| if (cursor != null) { | |
| cursor.close(); | |
| } | |
| }//End of try-catch block | |
| return result; | |
| } | |
| private static Bitmap rotate(Bitmap bm, int rotation) { | |
| if (rotation != 0) { | |
| Matrix matrix = new Matrix(); | |
| matrix.postRotate(rotation); | |
| Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); | |
| return bmOut; | |
| } | |
| return bm; | |
| } | |
| } |
| public class SimpleActivity { | |
| private static final int PICK_IMAGE_ID = 234; // the number doesn't matter | |
| public void onPickImage(View view) { | |
| Intent chooseImageIntent = ImagePicker.getPickImageIntent(this); | |
| startActivityForResult(chooseImageIntent, PICK_IMAGE_ID); | |
| } | |
| @Override | |
| protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
| switch(requestCode) { | |
| case PICK_IMAGE_ID: | |
| Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data); | |
| // TODO use bitmap | |
| break; | |
| default: | |
| super.onActivityResult(requestCode, resultCode, data); | |
| break; | |
| } | |
| } | |
| } |
| <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> |
i got blurred image on when i set on imgThumbnail ? how to fixed it ?
Hi mario,
I got a problem, my application crash on Samsung A6, get this message
D/ImagePicker: Intent: android.intent.action.PICK package: com.sec.android.gallery3d
D/ImagePicker: Intent: android.intent.action.PICK package: com.google.android.apps.photos
D/ImagePicker: Intent: android.media.action.IMAGE_CAPTURE package: com.sec.android.app.camera
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.arif.celmira, PID: 32369
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.example.arif.celmira/cache/tempImage exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)
at android.net.Uri.checkFileUriExposed(Uri.java:2356)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:944)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10492)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10498)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10477)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1616)
at android.app.Activity.startActivityForResult(Activity.java:4564)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)
at android.app.Activity.startActivityForResult(Activity.java:4522)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:751)
at com.example.arif.celmira.Kirimpembayaran.showFileChooser(Kirimpembayaran.java:186)
at com.example.arif.celmira.Kirimpembayaran.access$100(Kirimpembayaran.java:31)
at com.example.arif.celmira.Kirimpembayaran$2.onClick(Kirimpembayaran.java:112)
at android.view.View.performClick(View.java:6909)
at android.widget.TextView.performClick(TextView.java:12693)
at android.view.View$PerformClick.run(View.java:26200)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Application terminated.
Add code for Android 8.1:
public static Intent getPickImageIntent(Context context) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent chooserIntent = null;
https://stackoverflow.com/questions/48117511/exposed-beyond-app-through-clipdata-item-geturi
WHY are you removing an item from the intent list after having added it??? Doesnt that defeat the purpose???
Check out my solution I solved it. https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2#gistcomment-1593066