Search code examples
androidandroid-intentpathphoto-gallerygoogle-photos

Image Picker Intent - null path for online stored photos


I'm using an image picker intent, to allow users to choose an image from their gallery, I get it's path, and pass it then to a 3rd library.

It's working fine for most of the cases, but if I picked up an image from Google Photos (an image that is stored online) I get a null path, though that I get valid URI for both of the working and not working images.

Here is my Intent call:

Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

startActivityForResult(intent, RESULT_LOAD_IMAGE);

and here is onActivityResult:

    public void onActivityResult(int requestCode, int resultCode, Intent data) {

            Uri uri = data.getData();
            Log.e(getClass().getName(),"file uri = " + uri);

            String[] projection = {MediaStore.Images.Media.DATA};
            Cursor cursor = getActivity().getContentResolver().query(uri, projection,
                    null, null, null);
            if(cursor == null) return;
            Log.e(getClass().getName(),"file cursor = " + cursor);


            int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            Log.e(getClass().getName(),"file columnIndex = " + columnIndex);
            cursor.moveToFirst();



            // The crash happens here
            String photoPath = cursor.getString(columnIndex);
            Log.e(getClass().getName(),"file photo path = " + photoPath);

            cursor.close();
                cropImage(photoPath);

}

And here are the logs for working and not-working image:

Working image:

file uri = content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F105681/ORIGINAL/NONE/187859359

file cursor = android.content.ContentResolver$CursorWrapperInner@8953964

file columnIndex = 0

file photo path = /storage/emulated/0/DCIM/Camera/IMG_20190523_184830.jpg

Not working image:

file uri = content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253A4574915c-b4ac-40af-bc08-b1004670cab2/ORIGINAL/NONE/477302338

file cursor = android.content.ContentResolver$CursorWrapperInner@59448a4

file columnIndex = 0

file photo path = null

If there isn't way to avoid that error, is there a way instead to hide photos that are stored online and only show local ones?


Solution

  • The technique in your question has (at least) three problems:

    • Not every MediaStore entry has a value for DATA, as you're seeing

    • Not every non-null DATA value represents a filesystem path that you can access, as the MediaStore can get to content that you can't

    • The DATA column is not available on Android Q and higher

    In your case, the uCrop library accepts a Uri. Well-written Android libraries know how to handle a Uri, so you can just hand the Uri over to the library and it will take it from there.