Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Utility for picking an image from Gallery/Camera with Android Intents
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: m3ario@gmail.com
*/
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"/>
@qtringuyen

This comment has been minimized.

Copy link

@qtringuyen qtringuyen commented Oct 10, 2015

Hello Mariovc,

Thanks for your class file, they are very useful for me.
I can select image from Gallery and display to ImageView perfectly.
However, I got the RuntimeException error, when using Camera. After take picture and clicks Ok (device Nexus 5 with Android 6,0).
Here is the logcat:
0-10 21:23:41.987 27575-27604/com.example.tri.intentchooser E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0xb374fd70
10-10 21:23:52.089 27575-27575/com.example.tri.intentchooser D/ImagePicker﹕ getImageFromResult, resultCode: -1
10-10 21:23:52.094 27575-27575/com.example.tri.intentchooser D/ImagePicker﹕ selectedImage: null
10-10 21:23:52.098 27575-27575/com.example.tri.intentchooser D/AndroidRuntime﹕ Shutting down VM
10-10 21:23:52.112 27575-27575/com.example.tri.intentchooser E/AndroidRuntime﹕ FATAL EXCEPTION: main
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=234, result=-1, data=Intent { }} to activity {com.example.tri.intentchooser/com.example.tri.intentchooser.MainActivity}: java.lang.NullPointerException: uri
Caused by: java.lang.NullPointerException: uri
at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:60)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:922)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:865)
at com.example.tri.intentchooser.ImagePicker.decodeBitmap(ImagePicker.java:110)
at com.example.tri.intentchooser.ImagePicker.getImageResized(ImagePicker.java:133)
at com.example.tri.intentchooser.ImagePicker.getImageFromResult(ImagePicker.java:90)
at com.example.tri.intentchooser.MainActivity.onActivityResult(MainActivity.java:62)
at android.app.Activity.dispatchActivityResult(Activity.java:6428)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3089)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)

@RGU5Android

This comment has been minimized.

Copy link

@RGU5Android RGU5Android commented Oct 16, 2015

Thanks a lot.

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Oct 19, 2015

Hi qtringuyen,
I have not tried with Android 6.0 yet, but I could find a similar problem on StackOverflow. Check it out and tell us if it helped. Thanks for comment.

@castar123

This comment has been minimized.

Copy link

@castar123 castar123 commented Oct 23, 2015

Hi i test in nexus 5 an change this :

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);
    pickIntent.putExtra("return-data", true);
    pickIntent.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;

and ..................

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

    if(resultCode != RESULT_CANCELED){
        if (requestCode == PICK_IMAGE_ID) {
            if (data.getExtras() == null){
                Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data);
                profilePic.setImageBitmap(bitmap);
            }else{
                Bitmap photo = (Bitmap) data.getExtras().get("data");
                profilePic.setImageBitmap(photo);
            }
        }
    }
}

and works !!! i hope this help you and Thanks Mariovc

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Oct 27, 2015

Solved it with the last review. Line 58:

boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
@zontag

This comment has been minimized.

Copy link

@zontag zontag commented Nov 4, 2015

I translated this to Xamarin.Android and everything works fine. Thx!

@amaydiam

This comment has been minimized.

Copy link

@amaydiam amaydiam commented Nov 8, 2015

on Nexus Adroid M , if i choose any camera, camera apps not lauch

@mraffo

This comment has been minimized.

Copy link

@mraffo mraffo commented Nov 23, 2015

What about the app permissions of this? Because not found for me. In method OnActivityForResult always return null data and code 0. I have kitkat 4.4.4

@Shayne3000

This comment has been minimized.

Copy link

@Shayne3000 Shayne3000 commented Dec 7, 2015

@amaydiam....I experienced something similar. @Mariovc Please try run it on android 5.0 and 6.0 Nexus devices.

@vassilyvv

This comment has been minimized.

Copy link

@vassilyvv vassilyvv commented Dec 18, 2015

It was ok when I tested an app on samsung and other normal devices. But on CUBE (chineese pad) I've got error while starting an intent:

java.lang.NullPointerException
at kg.zuber.factory.utils.ImagePicker.getTempFile(ImagePicker.java:98)
at kg.zuber.factory.utils.ImagePicker.getPickImageIntent(ImagePicker.java:46)

I've tried to change getTempFile content to this one:

https://codeshare.io/VlgcB

Now can't apply photo after capturing - "yes, I want to use this photo" button doesn't work. How to solve the problem?

@vassilyvv

This comment has been minimized.

Copy link

@vassilyvv vassilyvv commented Dec 21, 2015

I solved my problem by adding

to manifest. Please, precise it at gist. Thank you!

@dkiwing

This comment has been minimized.

Copy link

@dkiwing dkiwing commented Dec 30, 2015

Thx a lot bro !

@ab95david

This comment has been minimized.

Copy link

@ab95david ab95david commented Feb 10, 2016

Man, this worked like a charm. Don't forget to add resultCode check in onActivityResult. Thanks a lot

@dm77

This comment has been minimized.

Copy link

@dm77 dm77 commented Feb 12, 2016

Thanks so much for this.

@firephantomassasin

This comment has been minimized.

Copy link

@firephantomassasin firephantomassasin commented Feb 15, 2016

How would i check if the return image is an image file? I want to filter image files only. On my android device i can select an image from file explorer and it shows all files and when i select non image file the code crash.

@yonetmen

This comment has been minimized.

Copy link

@yonetmen yonetmen commented Feb 16, 2016

Works fine as it is but it stops working when I want to add crop functionality to the images. It crops images but my imageView doesn't update with the new photo. I tried to add "intentName.putExtra("crop", "true); before adding intents to the addIntentsToList() method. Any idea what's the problem?

@bedanta

This comment has been minimized.

Copy link

@bedanta bedanta commented Feb 18, 2016

Very nicely done. Don't forget to close the cursor object once you open it.(it's considered a good habit).

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;
}
@oscargrgm

This comment has been minimized.

Copy link

@oscargrgm oscargrgm commented Mar 7, 2016

I have a problem with Android 5.1.1. The menu offers the option of choosing my image from Gallery, Photos (Google) or Camera.

It works perfectly if I choose the image from Photos or Camera, but when I choose Gallery, the system has the same behavior as selecting Camera (showing the second Log.e), so it doesn´t return me anything.

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == RESULT_OK) {
            if(requestCode == SELECT_PICTURE_REQUEST_CODE) {
                if(data.getExtras() == null) {
                    Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data);
                    logo_image.setImageBitmap(bitmap);
                    Log.e("FROM GALLERY OR PHOTOS", bitmap.toString());
                } else {
                    Bitmap photo = (Bitmap) data.getExtras().get("data");
                    logo_image.setImageBitmap(photo);
                    Log.e("FROM CAMERA", data.getExtras().toString());
                }
            }
        }
    }

Do anyone of you know how can I manage this? Thank you very much?

@erva

This comment has been minimized.

Copy link

@erva erva commented Mar 11, 2016

Thank for great code snippet! I have found issue:
If pick image from camera several times - temp file does not update. Temp files holds first picked photo from camera.
In same time picking from gallery works like a charm.

@niiapa

This comment has been minimized.

Copy link

@niiapa niiapa commented Mar 23, 2016

Any idea on how to get cropping functionality implemented here. I've been searching for days. I've tried using crop intents but it doesn't seem to work. I'm not even sure if it's what I'm doing wrong or whether it's solely the Lollipop OS problem because I have no devices with a lower version. Please advise.

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Mar 25, 2016

Sorry for the delay guys, and thank you for the comments.
@amaydiam and @Shayne3000 I have tried it with OnePlus One 5.1 and 6.0, it seems to work. Could you give some detail of what is going wrong?
@mraffo It will always return null data if you are using the camera
@zuberok what did you added?
@ab95david the check of the resultCode was on the ImagePicker side, to simplify it to the user side.
@heyou93 with this code, you can only select camera and gallery apps to provide images. What is the app you selected?
@yonetmen @niiapa this gist doesn't support cropping, but you can try another similar gist I did using the soundcloud library to crop images.
@bedanta Thank you for your contribution. Added it.
@oscargrgm Take a look to the code inside getImageFromResult to determine if it is camera o gallery. It is not the same you wrote on the onActivityResult method.
@ervinmartirosyan Is the bitmap returned always the first captured from camera? Have you tried with different camera apps? What is your device and Android version? Are you using the default camera app?

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Mar 25, 2016

I have changed the isCamera condition a bit, to take into account more camera apps like Camera FV-5 app.

        boolean isCamera = (imageReturnedIntent == null ||
                imageReturnedIntent.getData() == null  ||
                imageReturnedIntent.getData().toString().contains(imageFile.toString()));
@BMomani

This comment has been minimized.

Copy link

@BMomani BMomani commented Apr 7, 2016

what about run-time permission

@BMomani

This comment has been minimized.

Copy link

@BMomani BMomani commented Apr 9, 2016

Error on Marshmallow
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/11 from pid=31277, uid=10055 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()

here is full error
04-09 16:53:28.259 31277-31277/android.alcode.com.material E/AndroidRuntime: FATAL EXCEPTION: main Process: android.alcode.com.material, PID: 31277 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=236, result=-1, data=Intent { dat=content://media/external/images/media/11 }} to activity {android.alcode.com.material/android.alcode.com.material.AddPostAvtivity.AddPostAvtivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/11 from pid=31277, uid=10055 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() at android.app.ActivityThread.deliverResults(ActivityThread.java:3699) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/11 from pid=31277, uid=10055 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() at android.os.Parcel.readException(Parcel.java:1599) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146) at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:692) at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1104) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:942) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:865) at android.alcode.com.material.Uitility.ImagePicker.decodeBitmap(ImagePicker.java:111) at android.alcode.com.material.Uitility.ImagePicker.getImageResized(ImagePicker.java:133) at android.alcode.com.material.Uitility.ImagePicker.getImageFromResult(ImagePicker.java:91) at android.alcode.com.material.AddPostAvtivity.AddPostAvtivity.onActivityResult(AddPostAvtivity.java:76) at android.app.Activity.dispatchActivityResult(Activity.java:6428) at android.app.ActivityThread.deliverResults(ActivityThread.java:3695) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Apr 20, 2016

@MOMANI1 Checking permissions documentation, reading from cache doesn't need a READ_EXTERNAL_STORAGE permission request for Android M:

Also starting in API level 19, this permission is not required to read/write files in your application-specific directories returned by getExternalFilesDir(String) and getExternalCacheDir().

Did you changed the path for saving the temporal path?

Moreover, the camera/gallery app picked should handle permissions for using the camera or accessing to the external extorage.

Update: I have tried it with a Nexus 5 and a OnePlus One both with Marshmallow and no crash produced. Can someone else check if it happens and which phone was used to test?

@ramyatrouny

This comment has been minimized.

Copy link

@ramyatrouny ramyatrouny commented Apr 23, 2016

Can someone check what's is missing while i take photo from the camera the application crash, as well in the manifest it includes 2
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-permission android:name="android.permission.FLASHLIGHT" />
and in addition writing to the external storage and read external storage

what's missing ?

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Apr 25, 2016

@mba3gar Could you show us the crash log? and what Android version?

@jagamypriera

This comment has been minimized.

Copy link

@jagamypriera jagamypriera commented May 13, 2016

@mba3gar and @Mariovc I have same problem too

Android version 4.2.2

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

seems caused by this fileDescriptor.getFileDescriptor() at line 113

here the log
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131306, result=-1, data=Intent { act=inline-data (has extras) }} to activity {io.skipday.sinovik/io.skipday.sinovik.activities.MainActivity}: java.lang.NullPointerException at android.app.ActivityThread.deliverResults(ActivityThread.java:3571) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3614) at android.app.ActivityThread.access$1100(ActivityThread.java:166) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5455) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:966) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:733) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at io.skipday.sinovik.utils.ImagePicker.decodeBitmap(ImagePicker.java:117) at io.skipday.sinovik.utils.ImagePicker.getImageResized(ImagePicker.java:133) at io.skipday.sinovik.utils.ImagePicker.getImageFromResult(ImagePicker.java:91) at io.skipday.sinovik.fragments.KtpFragment.onActivityResult(KtpFragment.java:103) at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:176) at android.app.Activity.dispatchActivityResult(Activity.java:5415) at android.app.ActivityThread.deliverResults(ActivityThread.java:3567) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3614)  at android.app.ActivityThread.access$1100(ActivityThread.java:166)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:194)  at android.app.ActivityThread.main(ActivityThread.java:5455)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:525)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:966)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:733)  at dalvik.system.NativeStart.main(Native Method) 

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented May 17, 2016

@skipday Probably it is not at that line, but before at line 107 when openAssetFileDescriptor(theUri, "r"); is called and it returns null, causing a NullPointerException
Is it thrown a FileNotFoundException or something like that before that crash?
Anyway I am going to avoid the crash returning a null bitmap for the next update.

By the way, I have a clue that could be because no SD card neither emulated external storage is found, could that match for your case?
What is printed by this log: Log.d(TAG, "selectedImage: " + selectedImage);?

@jagamypriera

This comment has been minimized.

Copy link

@jagamypriera jagamypriera commented May 18, 2016

@Mariovc I got this
05-18 21:15:39.457 16680-16680/io.skipday.sinovik D/ImagePicker: selectedImage: file:///storage/sdcard1/Android/data/io.skipday.sinovik/cache/tempImage
But, there is no file tempImage in that directory

@jiawenzhang

This comment has been minimized.

Copy link

@jiawenzhang jiawenzhang commented May 27, 2016

To test on Android M, you need to targetSdkVersion 23 in build.gradle to enable runtime permission request. The code is not requesting any camera permission, and I believe it breaks on Android M.

@shihabmi7

This comment has been minimized.

Copy link

@shihabmi7 shihabmi7 commented May 29, 2016

Faced a null pointer, after added manifest permission then Solved.

**

<uses-feature android:name="android.hardware.camera"
    android:required="true" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />**
@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Jul 27, 2016

I have made a Github lib with this code and a sample app. You can visit it here

@KarWL

This comment has been minimized.

Copy link

@KarWL KarWL commented Aug 10, 2016

Hi Mariovc, thanks for the code. It help a lot. Never thought intent can do so much. (New in android mobile application development. apologize if that sounds silly)

@Mariovc

This comment has been minimized.

Copy link
Owner Author

@Mariovc Mariovc commented Aug 11, 2016

@KarWL Your comment helps me too. Thanks! Star the gist if you liked it, and keep learning!

@ocampogeric

This comment has been minimized.

Copy link

@ocampogeric ocampogeric commented Aug 16, 2016

Hello Mariovc, thanks so much, its work perfect. :)

@Thialyson

This comment has been minimized.

Copy link

@Thialyson Thialyson commented Sep 10, 2016

Thanks!

@Gisse

This comment has been minimized.

Copy link

@Gisse Gisse commented Sep 17, 2016

Brilliant, just brilliant

@WilliamSpruyt

This comment has been minimized.

Copy link

@WilliamSpruyt WilliamSpruyt commented Oct 6, 2016

This is great very classy.

@shihabmi7

This comment has been minimized.

Copy link

@shihabmi7 shihabmi7 commented Jan 7, 2017

How to get File Name from this class in Activity from intent?

@suleman-siddique

This comment has been minimized.

Copy link

@suleman-siddique suleman-siddique commented Jan 16, 2017

hey bro can you tell me the value of constant string that u r using in intent.chooser function i.e R.string.pick_image_intent_text
????????

@bpratapsingh

This comment has been minimized.

Copy link

@bpratapsingh bpratapsingh commented Jan 18, 2017

@suleman You can use any value you want to show the title of intent like 'Select Image'.

@surveshoeb

This comment has been minimized.

Copy link

@surveshoeb surveshoeb commented May 6, 2017

Thanx dude it works!!!!!

@Zaniyar

This comment has been minimized.

Copy link

@Zaniyar Zaniyar commented May 30, 2017

I wanted to have dynamic file names for each image.

public Intent getPickImageIntent(Context context) {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        imageName = "Selfie_" + timeStamp + "_.jpg";
        Intent chooserIntent = null;
        //...
        takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context,imageName)));
        //...

and in the getImageFromResult() I have right after the if(isCamera)else part:

            setImageFile(imageFile);

In my MainActivity I have a Button, which I use to upload my image to the server.

  File file = imagePicker.getImageFile();
  //file that should be uploaded

This works for the Image created by the Camera, but not the images selected from the Gallery.

E/Upload error:: /storage/emulated/0/Android/data/me.acme.myApp/cache/Selfie_20170530_032715_.jpg: open failed: ENOENT (No such file or directory)

How can I achieve that the upload button can find the original image from the gallery but upload it under the new generated name?

@JosueCarrillo

This comment has been minimized.

Copy link

@JosueCarrillo JosueCarrillo commented Jul 31, 2017

Can someone help me please, i'm triying to use this library to set and image into a Cardview inside a RecyclerView.Adapter how can this been done with the onActivityResult. Cheers

@caneryilmaz

This comment has been minimized.

Copy link

@caneryilmaz caneryilmaz commented Aug 14, 2017

thx for your effort but i think could use static instance and public method to singleton structure.Have good job :)

@Coder1121

This comment has been minimized.

Copy link

@Coder1121 Coder1121 commented Aug 22, 2017

Thanx alot for this code snippet however i was facing two issues
one of them was on saving picture from camera my activities were destroying and app was crashing but i fixed it by adding android:configChanges="orientation|screenSize"in my menifest file and the other issue for which i am still looking for solution is that when i click on imageview to call onPickImage and then pressback or cancel it my imageview disappears.

@kawnayeen

This comment has been minimized.

Copy link

@kawnayeen kawnayeen commented Aug 29, 2017

Thanks for your complete guideline. I've created an android library from this example for easy integration with existing project.

I've added method to get the image file also for uploading at server.

@AppHero2

This comment has been minimized.

Copy link

@AppHero2 AppHero2 commented Oct 3, 2017

How come it returns null data as result for camera? I have tested 2 devices LG (21), Sumsung (21)

@avierose

This comment has been minimized.

Copy link

@avierose avierose commented Oct 30, 2017

Works perfectly for up to API 23, but API 24 and up when selecting the camera option from the chooser, instead of opening the camera it returns to the activity and fills the imageView with white space.

Does anyone know how to get around this?

Tried it on both emulator and physical device running 7.0

@nathan-mersha

This comment has been minimized.

Copy link

@nathan-mersha nathan-mersha commented May 1, 2018

Thank you for a beautiful code.

@saddahussain

This comment has been minimized.

Copy link

@saddahussain saddahussain commented May 30, 2018

Does not work on Android Kitkat

@MakFCT

This comment has been minimized.

Copy link

@MakFCT MakFCT commented Jul 9, 2018

Hello, when i use the camera option my data from the "Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data);" comes null any idea why? Been debugging for hours can't figure out why.
Thanks for the awesome code so helpful!!

@jiya250

This comment has been minimized.

Copy link

@jiya250 jiya250 commented Oct 1, 2018

Worked like charm.
I added permission check for camera because on API lower than 23,my app had crashed.
And modified....

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult( requestCode, resultCode, data );

    if (requestCode == PICK_IMAGE_ID && resultCode == RESULT_OK){
        //Bundle bundle = data.getExtras();
        Bitmap bitmap = ImagePicker.getImageFromResult(this, resultCode, data);
        circleImageView.setImageBitmap(bitmap);

    }
    else{
   //To get image captured by camera
        Bundle bundle = data.getExtras();
        bitmap = (Bitmap) bundle.get("data");
        circleImageView.setImageBitmap(bitmap);
    }

}

@imran-samed

This comment has been minimized.

Copy link

@imran-samed imran-samed commented Oct 12, 2018

what if i want an uri onActivityResult
and not able to pick full size image in lollipop

@var2611

This comment has been minimized.

Copy link

@var2611 var2611 commented Oct 26, 2018

Update with file please use following changes,


public static Intent getPickImageIntent(Context context) {
        Intent chooserIntent = null;

        List<Intent> intentList = new ArrayList<>();

        Intent pickIntent = new Intent(Intent.ACTION_PICK,
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intentList = addIntentsToList(context, intentList, pickIntent);
        intentList = addIntentsToList(context, intentList, takePhotoIntent);

        if (intentList.size() > 0) {
            chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
                    "Select Image");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
        }

        return chooserIntent;
    }

public static Bitmap getImageFromResult(Context context, int resultCode,
                                            Intent intentData) {
        Log.d(TAG, "getImageFromResult, resultCode: " + resultCode);
        Bitmap bm = null;
        if (resultCode == Activity.RESULT_OK) {
            Uri selectedImage;
            boolean isCamera = (intentData == null || intentData.getData() == null);
            if (isCamera) {     /** CAMERA **/
                bm = (Bitmap) intentData.getExtras().get("data");
                String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), bm, "Image123", null);
                selectedImage = Uri.parse(path);
            } else {            /** ALBUM **/
                selectedImage = intentData.getData();
            }
            Log.d(TAG, "selectedImage: " + selectedImage);

            bm = getImageResized(context, selectedImage);
            int rotation = getRotation(context, selectedImage, isCamera);
            bm = rotate(bm, rotation);
        }
        return bm;
    }

Use Of Intent same as describe :

Intent intent = ImagePicker.getPickImageIntent(MainActivity.this); startActivityForResult(intent, 999);

On ActWithResult :
bitmap = ImagePicker.getImageFromResult(this, resultCode, data);

@var2611

This comment has been minimized.

Copy link

@var2611 var2611 commented Oct 27, 2018

Works perfectly for up to API 23, but API 24 and up when selecting the camera option from the chooser, instead of opening the camera it returns to the activity and fills the imageView with white space.

Does anyone know how to get around this?

Tried it on both emulator and physical device running 7.0

Try this https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2#gistcomment-1593066

@var2611

This comment has been minimized.

Copy link

@var2611 var2611 commented Oct 27, 2018

what if i want an uri onActivityResult
and not able to pick full size image in lollipop

Check out my solution I solved it. https://gist.github.com/Mariovc/f06e70ebe8ca52fbbbe2#gistcomment-1593066

@mahmudinm

This comment has been minimized.

Copy link

@mahmudinm mahmudinm commented Dec 16, 2018

i got blurred image on when i set on imgThumbnail ? how to fixed it ?

@arifrahman2592

This comment has been minimized.

Copy link

@arifrahman2592 arifrahman2592 commented Mar 10, 2019

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.

@K01egA

This comment has been minimized.

Copy link

@K01egA K01egA commented May 28, 2019

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

@nutechmobile

This comment has been minimized.

Copy link

@nutechmobile nutechmobile commented Sep 30, 2020

WHY are you removing an item from the intent list after having added it??? Doesnt that defeat the purpose???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment