How To Get Real File Path From Android Uri

In previous article Android Pick Multiple Image From Gallery Example we have learnt how to use Intent.ACTION_GET_CONTENT to open picture gallery to select and display images. We save all user selected image’s uri in a list. Then we can show them one by one when user want.

Use Intent.ACTION_GET_CONTENT intent, you can not only select images but you can select every document in android also. The only thing you need to do is to set the intent type as below.

openAlbumIntent.setType("*/*");

Please note, you must use above setType method to set at least one type, otherwise below exception will be thrown.

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT } 

In some cases, we do not only need to save the image uri, because the uri maybe changed later. So we need to save the real image to our app folder. And then use it later such as upload to server.

So we need to get the uri represent file real local path, then we can read it and save a copy to our app folder.

Because from android KitKat ( sdk version 19 ), the system returned uri is not real local file path uri, it is a content provider style uri, so we should parse the uri and get the real file local path by query related content provider ( image provider, audio provider, video provider and document provider ).

Below is get uri real local file path source code.

/* Get uri related content real local file path. */
private String getUriRealPath(Context ctx, Uri uri)
{
    String ret = "";

    if( isAboveKitKat() )
    {
        // Android OS above sdk version 19.
        ret = getUriRealPathAboveKitkat(ctx, uri);
    }else
    {
        // Android OS below sdk version 19
        ret = getImageRealPath(getContentResolver(), uri, null);
    }

    return ret;
}

private String getUriRealPathAboveKitkat(Context ctx, Uri uri)
{
    String ret = "";

    if(ctx != null && uri != null) {

        if(isContentUri(uri))
        {
            if(isGooglePhotoDoc(uri.getAuthority()))
            {
                ret = uri.getLastPathSegment();
            }else {
                ret = getImageRealPath(getContentResolver(), uri, null);
            }
        }else if(isFileUri(uri)) {
            ret = uri.getPath();
        }else if(isDocumentUri(ctx, uri)){

            // Get uri related document id.
            String documentId = DocumentsContract.getDocumentId(uri);

            // Get uri authority.
            String uriAuthority = uri.getAuthority();

            if(isMediaDoc(uriAuthority))
            {
                String idArr[] = documentId.split(":");
                if(idArr.length == 2)
                {
                    // First item is document type.
                    String docType = idArr[0];

                    // Second item is document real id.
                    String realDocId = idArr[1];

                    // Get content uri by document type.
                    Uri mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    if("image".equals(docType))
                    {
                        mediaContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    }else if("video".equals(docType))
                    {
                        mediaContentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    }else if("audio".equals(docType))
                    {
                        mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }

                    // Get where clause with real document id.
                    String whereClause = MediaStore.Images.Media._ID + " = " + realDocId;

                    ret = getImageRealPath(getContentResolver(), mediaContentUri, whereClause);
                }

            }else if(isDownloadDoc(uriAuthority))
            {
                // Build download uri.
                Uri downloadUri = Uri.parse("content://downloads/public_downloads");

                // Append download document id at uri end.
                Uri downloadUriAppendId = ContentUris.withAppendedId(downloadUri, Long.valueOf(documentId));

                ret = getImageRealPath(getContentResolver(), downloadUriAppendId, null);

            }else if(isExternalStoreDoc(uriAuthority))
            {
                String idArr[] = documentId.split(":");
                if(idArr.length == 2)
                {
                    String type = idArr[0];
                    String realDocId = idArr[1];

                    if("primary".equalsIgnoreCase(type))
                    {
                        ret = Environment.getExternalStorageDirectory() + "/" + realDocId;
                    }
                }
            }
        }
    }

    return ret;
}

/* Check whether current android os version is bigger than kitkat or not. */
private boolean isAboveKitKat()
{
    boolean ret = false;
    ret = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    return ret;
}

/* Check whether this uri represent a document or not. */
private boolean isDocumentUri(Context ctx, Uri uri)
{
    boolean ret = false;
    if(ctx != null && uri != null) {
        ret = DocumentsContract.isDocumentUri(ctx, uri);
    }
    return ret;
}

/* Check whether this uri is a content uri or not.
*  content uri like content://media/external/images/media/1302716
*  */
private boolean isContentUri(Uri uri)
{
    boolean ret = false;
    if(uri != null) {
        String uriSchema = uri.getScheme();
        if("content".equalsIgnoreCase(uriSchema))
        {
            ret = true;
        }
    }
    return ret;
}

/* Check whether this uri is a file uri or not.
*  file uri like file:///storage/41B7-12F1/DCIM/Camera/IMG_20180211_095139.jpg
* */
private boolean isFileUri(Uri uri)
{
    boolean ret = false;
    if(uri != null) {
        String uriSchema = uri.getScheme();
        if("file".equalsIgnoreCase(uriSchema))
        {
            ret = true;
        }
    }
    return ret;
}


/* Check whether this document is provided by ExternalStorageProvider. */
private boolean isExternalStoreDoc(String uriAuthority)
{
    boolean ret = false;

    if("com.android.externalstorage.documents".equals(uriAuthority))
    {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by DownloadsProvider. */
private boolean isDownloadDoc(String uriAuthority)
{
    boolean ret = false;

    if("com.android.providers.downloads.documents".equals(uriAuthority))
    {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by MediaProvider. */
private boolean isMediaDoc(String uriAuthority)
{
    boolean ret = false;

    if("com.android.providers.media.documents".equals(uriAuthority))
    {
        ret = true;
    }

    return ret;
}

/* Check whether this document is provided by google photos. */
private boolean isGooglePhotoDoc(String uriAuthority)
{
    boolean ret = false;

    if("com.google.android.apps.photos.content".equals(uriAuthority))
    {
        ret = true;
    }

    return ret;
}

/* Return uri represented document file real local path.*/
private String getImageRealPath(ContentResolver contentResolver, Uri uri, String whereClause)
{
    String ret = "";

    // Query the uri with condition.
    Cursor cursor = contentResolver.query(uri, null, whereClause, null, null);

    if(cursor!=null)
    {
        boolean moveToFirst = cursor.moveToFirst();
        if(moveToFirst)
        {

            // Get columns name by uri type.
            String columnName = MediaStore.Images.Media.DATA;

            if( uri==MediaStore.Images.Media.EXTERNAL_CONTENT_URI )
            {
                columnName = MediaStore.Images.Media.DATA;
            }else if( uri==MediaStore.Audio.Media.EXTERNAL_CONTENT_URI )
            {
                columnName = MediaStore.Audio.Media.DATA;
            }else if( uri==MediaStore.Video.Media.EXTERNAL_CONTENT_URI )
            {
                columnName = MediaStore.Video.Media.DATA;
            }

            // Get column index.
            int imageColumnIndex = cursor.getColumnIndex(columnName);

            // Get column value which is the uri related file local path.
            ret = cursor.getString(imageColumnIndex);
        }
    }

    return ret;
}
(Visited 10,333 times, 6 visits today)
READ :   How To Create New Android Studio Project

7 Comments


  1. You are my hero, such a mess on documenting this on google’s part

    Reply

  2. Hey, Thank you for the code. It works for most apps but does not work for images shared from WhatsApp. I am trying to catch the images shared from WhatsApp to my app but the uri of the images does not give the real path. When i’m using your code it gives the error:

    java.lang.IllegalStateException: Couldn’t read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly

    Can you please suggest something to fix it.
    Thank you

    Reply

    1. From the error message, it said the col number is -1 which is not correct, because the minimum col value should be 0.

      I think you should set a breakpoint at where the error occurred, and debug into it to fix this error.

      Reply

  3. Jerry. Your code is wonderful. This helped me a lot with my school project. But how did you learn all this if the info is not in the Android documentation?

    Reply

  4. Why do I feel that there is a shorter way to get this done??

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.