How to get file path of image from URI in Android Lollipop?
Asked Answered
M

4

6

I want to create an image picker for Android Lollipop. I use Intent.ACTION_GET_CONTENT to choose my picture but I cannot get the path of selected image from URI, which the dialog picker returned.

I tried codes from these threads:

retrieve absolute path when select image from gallery kitkat android

https://chintankhetiya.wordpress.com/2013/12/14/picture-selection-from-camera-gallery/

but all of them return null. Can any one help me?

Masson answered 15/4, 2015 at 9:49 Comment(1)
take a look on this question: #21018425Ennead
G
13

Try

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {
    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri) {
        Log.variable("uri", uri.getPath());
        String filePath = "";
        if (DocumentsContract.isDocumentUri(context, uri)) {
            String wholeID = DocumentsContract.getDocumentId(uri);
            Log.variable("wholeID", wholeID);
// Split at colon, use second item in the array
            String[] splits = wholeID.split(":");
            if (splits.length == 2) {
                String id = splits[1];

                String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
                String sel = MediaStore.Images.Media._ID + "=?";
                Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        column, sel, new String[]{id}, null);
                int columnIndex = cursor.getColumnIndex(column[0]);
                if (cursor.moveToFirst()) {
                    filePath = cursor.getString(columnIndex);
                }
                cursor.close();
            }
        } else {
            filePath = uri.getPath();
        }
        return filePath;
    }

    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
        String[] proj = {MediaStore.Images.Media.DATA};
        String result = null;
        CursorLoader cursorLoader = new CursorLoader(
                context,
                contentUri, proj, null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();
        if (cursor != null) {
            int column_index =
                    cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(column_index);
        }
        return result;
    }

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
        int column_index
                = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

and use:

private String uriToFilename(Uri uri) {
    String path = null;

    if (Build.VERSION.SDK_INT < 11) {
        path = RealPathUtil.getRealPathFromURI_BelowAPI11(mContext, uri);
    } else if (Build.VERSION.SDK_INT < 19) {
        path = RealPathUtil.getRealPathFromURI_API11to18(mContext, uri);
    } else {
        path = RealPathUtil.getRealPathFromURI_API19(mContext, uri);
    }

    return path;
}

works for me in must cases (not works for download app)

Glennieglennis answered 17/4, 2015 at 13:1 Comment(0)
Q
3

Try this little function:

public static String getRealPathFromUri(Uri uri) {
    String result = "";
    String documentID;
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        String[] pathParts = uri.getPath().split("/");
        documentID = pathParts[pathParts.length - 1];
    } else {
        String pathSegments[] = uri.getLastPathSegment().split(":");
        documentID = pathSegments[pathSegments.length - 1];
    }
    String mediaPath = MediaStore.Images.Media.DATA;
    Cursor imageCursor = getContentResolver().query(uri, new String[]{mediaPath}, MediaStore.Images.Media._ID + "=" + documentID, null, null);
    if (imageCursor.moveToFirst()) {
        result = imageCursor.getString(imageCursor.getColumnIndex(mediaPath));
    }
    return result;
}
Quesada answered 4/5, 2016 at 7:6 Comment(2)
This helped me a lot, I was looking for code that works in Lollipop your answer was perfect for me, thanks!Taxpayer
On Nougat, passing in an image content Uri, this is returning null.Argumentation
S
1

This work for me.

I created a Util class RealPathUtil (there are some little differences with the class in the @Artem answer):

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

public class RealPathUtil {

    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API19(Context context, Uri uri) {
        String filePath = "";
        String wholeID = DocumentsContract.getDocumentId(uri);

        // Split at colon, use second item in the array
        String id = wholeID.split(":")[1];

        String[] column = { MediaStore.Images.Media.DATA };

        // where id is equal to
        String sel = MediaStore.Images.Media._ID + "=?";

        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                column, sel, new String[]{ id }, null);

        assert cursor != null;
        int columnIndex = cursor.getColumnIndex(column[0]);

        if (cursor.moveToFirst()) {
            filePath = cursor.getString(columnIndex);
        }
        cursor.close();
        return filePath;
    }


    @SuppressLint("NewApi")
    public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
        String[] proj = { MediaStore.Images.Media.DATA };
        String result = null;

        CursorLoader cursorLoader = new CursorLoader(
                context,
                contentUri, proj, null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();

        if(cursor != null){
            int column_index =
                    cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            result = cursor.getString(column_index);
        }
        return result;
    }

    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
        Cursor cursor = null;

        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
            assert cursor != null;
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

}

Then, in my app code, I used:

private String getPathFromUri(Uri uri) {
    if (Build.VERSION.SDK_INT < 11)
        return RealPathUtil.getRealPathFromURI_BelowAPI11(getContext(), uri);
    else if (Build.VERSION.SDK_INT < 19)
        return RealPathUtil.getRealPathFromURI_API11to18(getContext(), uri);
    else
        return RealPathUtil.getRealPathFromURI_API19(getContext(), uri);
}
Sheol answered 6/11, 2015 at 19:13 Comment(0)
S
0

Make Sure You are Giving Permission in the Android Manifest!

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Stoke answered 19/3, 2016 at 22:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.