Convert content:// URI to actual path in Android 4.4
Asked Answered
A

11

67

I tried a solution (see below) that works fine, except in Android 4.4 the call to startActivityForResult() brings up an activity titled "Open from", which has "Recent", "Images", "Downloads" as well as several apps to pick from. When I choose "Images" and try to resolve the returned content URI (using the code below), the call to cursor.getString() returns null. If I choose the exact same file using the Gallery app, cursor.getString() returns a file path. I've only tested this in API levels 16 and 19. Everything works as expected in 16. As far as 19 goes, I have to choose the Gallery or other app or it doesn't work.

private String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;
    try { 
        String[] proj = { MediaStore.Images.Media.DATA };
        cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String path = cursor.getString(column_index);

        return path;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
Ahmed answered 14/11, 2013 at 18:18 Comment(0)
H
104

This will get the file path from the MediaProvider, DownloadsProvider, and ExternalStorageProvider, while falling back to the unofficial ContentProvider method you mention.

   /**
 * Get a file path from a Uri. This will get the the path for Storage Access
 * Framework Documents, as well as the _data field for the MediaStore and
 * other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @author paulburke
 */
public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[] {
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context The context.
 * @param uri The Uri to query.
 * @param selection (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri, String selection,
        String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

source aFileChooser

Header answered 3/12, 2014 at 11:53 Comment(15)
This worked beautifully. One thing to add was that for my uploading code (via retrofit) to work, I had to append "file://" to the beginning of the returned String.Fasta
So, how to handle non-primary volumes?Brackely
@Kishan Vaghela no need to include these methods, everything is done in library i mentioned in my answer. Check my answer.Inconsonant
Hi..Thanks for the answer... But it is not working in my case.We are getting path something like - content://com.google.android.apps.docs.storage/..... Can any one help us with this?Buggy
Where is your file is located? Can you find it from the file manager? As per your URI, I think it's in app dir of Google Doc application. Am I right?Header
Works for URIs like "content://downloads/all_downloads/47", but it doesn't for "content://downloads/my_downloads/47" (produced by Chrome when you open a file that has just been downloaded)Polson
@KishanVaghela getPath() will return null for external sdcard files.Any solution for that??Illgotten
this utils is not perfect and will cause java.lang.RuntimeException on On Galaxy S7, Andorid N API24. the error is column '_data' does not exist when taking photos by camera.Ridgway
What will happen if the storage is a memory card? non-primary get's null if use this method in Android LLexicon
What about ContactContract? For: content://com.android.contacts/contacts/as_vcard/XXXXXXUnbelt
throws exception for files in the Downloads folder in OreoSonics
@KishanVaghela This code doesnot work for files from GoogleDrive and Uri's of type =>"content://com.google.android.apps.docs.storage/document/acc%3D3%3Bdoc%3D1259"Fusillade
@Sonics did you find a solution, if so, can you please share?Onfroi
Works fine with my phone's file manager but not with the EZ File explorer app.Craniometer
Input Uri: content://com.android.providers.downloads.documents/document/1603 Path: content://downloads/public_downloads/1603 Giving error: java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/1603Kellda
U
51

Convert content:// URI to actual path in Android 4.4

There is no reliable way to do this on any Android version. A content:// Uri does not have to represent a file on the filesystem, let alone one that you are able to access.

Android 4.4's changes to offer the storage framework simply increases the frequency with which you will encounter content:// Uri values.

If you get a content:// Uri, please consume it using a ContentResolver and methods like openInputStream() and openOutputStream().

Uniseptate answered 14/11, 2013 at 18:23 Comment(8)
Is it incorrect to assume, whenever using Intent.ACTION_GET_CONTENT to select videos specifically, that MediaStore provider will hold information related to the returned content URI ?Ev
@TomReznik: There is no requirement that ACTION_GET_CONTENT to return a Uri that has been indexed by MediaStore.Uniseptate
@Uniseptate Thanks for the answer, everyone seems to have been doing what the poster did even though there was never any guarantee it would always work. My question now is, if we need a File and not an InputStream, does that mean we have to convert the InputStream to a File?Chinfest
@a_secret: First, I'd try finding some other solution to whatever problem you are trying to solve, one that does not involve a File (see this rant of mine from last year on this topic). Otherwise, yes, you will need to stream the contents of the InputStream to your own local file.Uniseptate
@Uniseptate Thank you for the advice; I have indeed already reverted to using the InputStream instead! The question was more just that I wanted to make sure my understanding was correct(as an intellectual curiosity). Thanks!Chinfest
its very bad, we cannot use java.io.file !! we must change old codes.Around
@Uniseptate I am getting java.lang.IllegalArgumentException: Unknown URI: content://downloads/public_downloads/6201 using context.getContentResolver().openInputStream(srcUri).I am fetching Uri using implicit intent..The issue happeneing in single device only!Amphistylar
@AndroidDeveloper: You might want to ask a separate Stack Overflow question, with a minimal reproducible example showing your code and the full stack trace.Uniseptate
P
11

I have been facing this problem too, but in my case, what I wanted to do was to specify a concrete Uri to the Gallery so I can use crop later. Looks like in the new Document Browser of KitKat we can't do that anymore unless you choose galery in the navigation drawer, and, like you said, open the image or file directly from there.

In the Uri case, you can still retrieve the path when opening fromt he Document Browser.

    Intent dataIntent= new Intent(Intent.ACTION_GET_CONTENT);
    dataIntent.setType("image/*"); //Or whatever type you need

And then in onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == ACTIVITY_SELECT_IMAGE && resultCode == RESULT_OK) {
        myUri = data.getData();
        String path = myUri.getPath();
        openPath(myUri);

    }
}

If you need then to open a file with that path, you just have yo use a Content Resolver:

public void openPath(Uri uri){
    InputStream is = null;
    try {
        is = getContentResolver().openInputStream(uri);
        //Convert your stream to data here
        is.close();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
Pastiche answered 13/12, 2013 at 11:12 Comment(1)
This is a solution what i want.Olympia
C
9

It is introduced in a Google API. You can try this:

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
            getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}
Courageous answered 25/9, 2015 at 3:27 Comment(3)
How about when I need the file?Nisus
Started getting java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider exceptionRetentive
Best solution!!Pasture
G
0

If you really need a file path. First, get the data using ContentResolver. Then, you can save the data to a temp file and use that path.

(I had to use a library with File object in a function parameter.)

Getaway answered 20/5, 2014 at 2:33 Comment(0)
R
0

Thanks to @FireBear, I modified answer now one will get path of media file

String filePath=saveBitmap(activity,getBitmapFromUri(imageUri),"tmpFile").getPath();

private Bitmap getBitmapFromUri(Context context, Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
                context.getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
    }

    private File saveBitmap(Context context, Bitmap bitmap, String name) {
        File filesDir = context.getFilesDir();
        File imageFile = new File(filesDir, name + ".jpg");
        OutputStream os;
        try {
            os = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
            os.flush();
            os.close();
        } catch (Exception e) {
            //Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
        }
        return imageFile;
    }
Retentive answered 12/10, 2017 at 18:52 Comment(0)
B
0

I know it does not answer the question itself, but as @CommonsWare sad, SAF was not meant to use this way.

Maybe an option for this is creating a copy of the file on the app's external files dir, use it and then delete it.

public File createFileCopy(Context context, DocumentFile file) {

        if (file == null || !file.exists() || file.getName() == null) {
            throw new IllegalArgumentException("The file must no be null, and must exist, and must have a name.");
        }

        File fileCopy = new File(context.getExternalFilesDir(null).getAbsolutePath(), file.getName());

        try {

            android.os.FileUtils.copy(openFileInputStream(file), new FileOutputStream(fileCopy));

            return fileCopy;

        } catch (Exception e) {
          // do whateveer you want with this exceeption
            e.printStackTrace();
        }
        return null;
    }
Bellbird answered 23/4, 2021 at 4:7 Comment(0)
L
0

I tried in a different way. each answer on stackoverflow was having some kind of issue, either it leads to some kind of crash or dosen't works out. the first answer above won't work for finding URI from whatsApp media.

below solution is all rounder solution worked for me. I have copied complete PathUtils class here. use getpath() function for the path.

public class PathUtils {

    private static final int BUFFER_SIZE = 1024 * 2;

    public static String getPath(Context context, Uri contentUri) {
        String fileName = getFileName(contentUri);
        if (!TextUtils.isEmpty(fileName)) {
            File copyFile = new File(context.getCacheDir()  + fileName+contentUri.getScheme());
            copy(context, contentUri, copyFile);
            return copyFile.getAbsolutePath();
        }
        return null;
    }

    public static String getFileName(Uri uri) {
        if (uri == null) return null;
        String fileName = null;
        String path = uri.getPath();
        int cut = path.lastIndexOf('/');
        if (cut != -1) {
            fileName = path.substring(cut + 1);
        }
        return fileName;
    }

    public static void copy(Context context, Uri srcUri, File dstFile) {
        try {
            InputStream inputStream = context.getContentResolver().openInputStream(srcUri);
            if (inputStream == null) return;
            OutputStream outputStream = new FileOutputStream(dstFile);
            copyMain(inputStream, outputStream);
            inputStream.close();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static int copyMain(InputStream input, OutputStream output) throws Exception, IOException {
        byte[] buffer = new byte[BUFFER_SIZE];

        BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
        BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
        int count = 0, n = 0;
        try {
            while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
                out.write(buffer, 0, n);
                count += n;
            }
            out.flush();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                Log.e(e.getMessage(), e.toString());
            }
            try {
                in.close();
            } catch (IOException e) {
                Log.e(e.getMessage(), e.toString());
            }
        }
        return count;
    }
}
Lusty answered 4/2, 2023 at 9:35 Comment(0)
L
0

This function will change the content uri to real path.

fun getRealPathFromUri(uri: Uri): String? {
val projection = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(uri, projection, null, null, null) ?: return null
val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
val filePath = cursor.getString(columnIndex)
cursor.close()
return filePath }

same code in java

public String getRealPathFromUri(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
if (cursor == null) {
    return null;
}
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String filePath = cursor.getString(columnIndex);
cursor.close();
return filePath; }
Lalittah answered 12/4, 2023 at 9:47 Comment(0)
R
-1

Convert content:// URI to actual path in Android.

I have managed this fileUtils Class From a SO answer, and get path from all kinds of Uri:

package com.alquran.tafhimul_quran.Common;


import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.io.File;

public class UtilsFile {




    private final static String PUBLIC_DOWNLOAD_PATH = "content://downloads/public_downloads";


    private final static String EXTERNAL_STORAGE_DOCUMENTS_PATH = "com.android.externalstorage.documents";


    private final static String DOWNLOAD_DOCUMENTS_PATH = "com.android.providers.downloads.documents";


    private final static String MEDIA_DOCUMENTS_PATH = "com.android.providers.media.documents";


    private final static String PHOTO_CONTENTS_PATH = "com.google.android.apps.photos.content";


    private Boolean isExternalStorageDocument(Uri uri) {
        return EXTERNAL_STORAGE_DOCUMENTS_PATH.equals(uri.getAuthority());

    }
    private Boolean isPublicDocument(Uri uri) {
        return PUBLIC_DOWNLOAD_PATH.equals(uri.getAuthority());

    }


    private Boolean isDownloadsDocument(Uri uri) {
        return DOWNLOAD_DOCUMENTS_PATH.equals(uri.getAuthority());

    }

    private Boolean isMediaDocument(Uri uri) {
        return MEDIA_DOCUMENTS_PATH.equals(uri.getAuthority());
    }


    private Boolean isGooglePhotosUri(Uri uri) {
        return MEDIA_DOCUMENTS_PATH.equals(uri.getAuthority());

    }
    private Boolean isPhotoContentUri(Uri uri) {
        return PHOTO_CONTENTS_PATH.equals(uri.getAuthority());

    }



    private String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {

        Cursor cursor = null;
        //String column = "_data" REMOVED IN FAVOR OF NULL FOR ALL
        //String projection = arrayOf(column) REMOVED IN FAVOR OF PROJECTION FOR ALL
        try {
            cursor = context.getContentResolver().query(uri, null, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DISPLAY_NAME);
                return cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            Log.e("PathUtils", "Error getting uri for cursor to read file: " + e.getMessage());
        } finally {
            assert cursor != null;
            cursor.close();
        }
        return null;

    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public  String getFullPathFromContentUri(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        String filePath="";
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }//non-primary e.g sd card
                else {
                    if (Build.VERSION.SDK_INT > 20) {
                        //getExternalMediaDirs() added in API 21
                        File[] extenal = context.getExternalMediaDirs();
                        for (File f : extenal) {
                            filePath = f.getAbsolutePath();
                            if (filePath.contains(type)) {
                                int endIndex = filePath.indexOf("Android");
                                filePath = filePath.substring(0, endIndex) + split[1];
                            }
                        }
                    }else{
                        filePath = "/storage/" + type + "/" + split[1];
                    }
                    return filePath;
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                String fileName = getDataColumn(context,  uri,null, null);
                String uriToReturn = null;
                if (fileName != null) {
                    uriToReturn = Uri.withAppendedPath(
                            Uri.parse(
                                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()), fileName
                    ).toString();
                }
                return uriToReturn;
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                Cursor cursor = null;
                final String column = "_data";
                final String[] projection = {
                        column
                };

                try {
                    cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                            null);
                    if (cursor != null && cursor.moveToFirst()) {
                        final int column_index = cursor.getColumnIndexOrThrow(column);
                        return cursor.getString(column_index);
                    }
                } finally {
                    if (cursor != null)
                        cursor.close();
                }
                return null;
            }

        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }
        else if (isPublicDocument(uri)){
            String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse(PUBLIC_DOWNLOAD_PATH), Long.parseLong(id));
            String[] projection = {MediaStore.Images.Media.DATA};
            @SuppressLint("Recycle") Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null);

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

        return null;
    }

}

Usage of OnActivityResult:

if (requestCode == PICK_AUDIO_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();

            UtilsFile utilsFile = new UtilsFile();
            String filePath = utilsFile.getFullPathFromContentUri(mContext, uri);
            System.out.println("Audio File Path : "+ filePath);

           // audioString = audioFileToString(filePath);

        }
Rathbone answered 29/6, 2022 at 23:45 Comment(0)
L
-2

Get a file path from a Uri:- I had created a Util class that will get the path for Storage Access Framework Documents, as well as the _data field for the MediaStore and other file-based ContentProviders.

ConvertUriToFilePath :-

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.RequiresApi;

public class ConvertUriToFilePath {
    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static String getPathFromURI(final Context context, final Uri uri) {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        // ExternalStorageProvider
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        Uri contentUri = null;
        if ("image".equals(type)) {
            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if ("video".equals(type)) {
            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else if ("audio".equals(type)) {
            contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        }

        final String selection = "_id=?";
        final String[] selectionArgs = new String[]{
                split[1]
        };

        return getDataColumn(context, contentUri, selection, selectionArgs);


        //  return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

/**
 * Get the value of the data column for this Uri. This is useful for
 * MediaStore Uris, and other file-based ContentProviders.
 *
 * @param context       The context.
 * @param uri           The Uri to query.
 * @param selection     (Optional) Filter used in the query.
 * @param selectionArgs (Optional) Selection arguments used in the query.
 * @return The value of the _data column, which is typically a file path.
 */
public static String getDataColumn(Context context, Uri uri, String selection,
                                   String[] selectionArgs) {
    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };
    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}


/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is ExternalStorageProvider.
 */
public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is DownloadsProvider.
 */
public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

/**
 * @param uri The Uri to check.
 * @return Whether the Uri authority is MediaProvider.
 */
public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

}

Example Code :

// Just call this function of ConvertUriToFilePath class and it will return full path of file URI.

 String actualFilepath= ConvertUriToFilePath.getPathFromURI(activity,tempUri);
Luxury answered 28/4, 2017 at 12:10 Comment(2)
I am getting null for content://com.android.chrome.FileProvider/images/screenshot/15078254878111317987290.jpgRetentive
The benefit of posting the actual code provided at a link is that it is not lost when the link breaks. Unfortunately, your answer no longer provides anything but a page full of ads.Unmindful

© 2022 - 2024 — McMap. All rights reserved.