'Getting filename from uri

How can I get the name of a file from a uri returned in OnActivityResult, I tried using this bit of code

Uri uri = data.getData(); String fileName = uri.getLastPathSegment();

but it just returns something like this images:3565. The file that is picked is not only of image type it can be a video, or document file, etc.... I realized that the uri returned from kitkat is different than previous versions as well, I would be interested in a method that works for pre kitkat as well.



Solution 1:[1]

This is the code I'm using to get informations from a Uri :

public static class FileMetaData
{
    public String displayName;
    public long size;
    public String mimeType;
    public String path;

    @Override
    public String toString()
    {
        return "name : " + displayName + " ; size : " + size + " ; path : " + path + " ; mime : " + mimeType;
    }
}


public static FileMetaData getFileMetaData(Context context, Uri uri)
{
    FileMetaData fileMetaData = new FileMetaData();

    if ("file".equalsIgnoreCase(uri.getScheme()))
    {
        File file = new File(uri.getPath());
        fileMetaData.displayName = file.getName();
        fileMetaData.size = file.length();
        fileMetaData.path = file.getPath();

        return fileMetaData;
    }
    else
    {
        ContentResolver contentResolver = context.getContentResolver();
        Cursor cursor = contentResolver.query(uri, null, null, null, null);
        fileMetaData.mimeType = contentResolver.getType(uri);

        try
        {
            if (cursor != null && cursor.moveToFirst())
            {
                int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
                fileMetaData.displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));

                if (!cursor.isNull(sizeIndex))
                    fileMetaData.size = cursor.getLong(sizeIndex);
                else
                    fileMetaData.size = -1;

                try
                {
                    fileMetaData.path = cursor.getString(cursor.getColumnIndexOrThrow("_data"));
                }
                catch (Exception e)
                {
                    // DO NOTHING, _data does not exist
                }

                return fileMetaData;
            }
        }
        catch (Exception e)
        {
            Log.e(Log.TAG_CODE, e);
        }
        finally
        {
            if (cursor != null)
                cursor.close();
        }

        return null;
    }
}

Solution 2:[2]

Maybe this is too trivial, but in my case it worked:

DocumentFile.fromSingleUri(context, uri).getName();

(simplified, without null pointer checks). Similar with other metadata.

Solution 3:[3]

I think the most straightforward and easy way to retrieve information from an URI is using DocumentFile. Just create a new DocumentFile using context and your URI.

DocumentFile file = DocumentFile.fromSingleUri(context, uri);

Then you can retrieve various information from it.

String fileName = file.getName();
long fileSize = file.length();
String mimeType = file.getType(); //get the mime type

Note that file.getName() will return file name with extension (e.g. video.mp4)

Solution 4:[4]

For kotlin just use the name atttribute from the File class:

val fileName = File(uri.path).name

Solution 5:[5]

According to Android Documentation

/*
     * Get the file's content URI from the incoming Intent,
     * then query the server app to get the file's display name
     * and size.
     */
    returnIntent.data?.let { returnUri ->
        contentResolver.query(returnUri, null, null, null, null)
    }?.use { cursor ->
        /*
         * Get the column indexes of the data in the Cursor,
         * move to the first row in the Cursor, get the data,
         * and display it.
         */
        val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
        cursor.moveToFirst()
        findViewById<TextView>(R.id.filename_text).text = cursor.getString(nameIndex)
        findViewById<TextView>(R.id.filesize_text).text = cursor.getLong(sizeIndex).toString()
        ...
    }

https://developer.android.com/training/secure-file-sharing/retrieve-info

Solution 6:[6]

fun Uri.getFileNameWithExtension(context: Context): String? {
    val name = this.path?.let { path -> File(path).name }.orEmpty()
    val extension = MimeTypeMap.getSingleton()
        .getExtensionFromMimeType(getMimeType(context)).orEmpty()

    return if (name.isNotEmpty() && extension.isNotEmpty()) "$name.$extension" else null
}

fun Uri.getMimeType(context: Context): String? {
    return when (scheme) {
        ContentResolver.SCHEME_CONTENT -> context.contentResolver.getType(this)
        ContentResolver.SCHEME_FILE -> MimeTypeMap.getSingleton().getMimeTypeFromExtension(
            MimeTypeMap.getFileExtensionFromUrl(toString()).toLowerCase(Locale.US)
        )
        else -> null
    }
}

Solution 7:[7]

This worked for me. Have a look at the official documentation here

String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME};
        ContentResolver cr = mctx.getContentResolver();
        Cursor metaCursor = cr.query(uri[0], projection, null, null, null);
        if (metaCursor != null) {
            try {
                if (metaCursor.moveToFirst()) {
                    realFileName = metaCursor.getString(0);
                }
            } finally {
                metaCursor.close();
            }
        }

Solution 8:[8]

If I use ContentResolver, it returns null if uri is from camera captured image in my case so simple function to get file name from uri

public static String getFileNameFromURI(@NonNull Context context,  @NonNull Uri uri) {
        String result = null;
        if("file".equalsIgnoreCase(uri.getScheme())){
            result= new File(uri.getPath()).getName();
        }
        else {
            Cursor c = null;
            try {
                c = context.getContentResolver().query(uri, null, null, null, null);
                c.moveToFirst();
                result = c.getString(c.getColumnIndex(OpenableColumns.DISPLAY_NAME));
            } catch (Exception e) {
                // error occurs
            } finally {
                if (c != null) {
                    c.close();
                }
            }
        }
        return result;
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Quanturium
Solution 2 Andreas K. aus M.
Solution 3 Bryan Amirul Husna
Solution 4 Sam Chen
Solution 5 mikail yusuf
Solution 6
Solution 7 pcodex
Solution 8