How to get Actual file path of a pdf file in Android Pie? [duplicate]
Asked Answered
R

1

6

currently I am facing an issue of not able to retrieve the actual file path of pdf. I tried all the solutions I got, but not able to get the actual file path in Android Pie. Any help will be appreciable.

Code:- Intent to open file manager and allow to select pdf file.

Intent intent = new Intent();
intent.setType("application/pdf");
intent.setAction(Intent.ACTION_GET_CONTENT);
String[] mimetypes = {"application/pdf"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(Intent.createChooser(intent, "Choose Pdf"), REQUEST_CODE_SELECT_IMAGE);

After clicking/selecting any pdf file compiler moves to onActivityResult:-

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_SELECT_IMAGE:
            String template_file_uri = null;
            String extension = null;
            switch (resultCode) {
                case Activity.RESULT_OK:
                    try {

                        String path = null;
                        if (android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
                            Uri selectedFileUri = data.getData();
                            String mimeType = getContentResolver().getType(selectedFileUri);
                            Log.e(TAG, "onActivityResult() REQUEST_CODE_SELECT_IMAGE RESULT_OK uri : " + selectedFileUri + " mimetype " + mimeType);
                            Log.e(TAG, ":::>>selectedFileUri::: " + selectedFileUri);

                            int lastDot = selectedFileUri.toString().lastIndexOf('.');
                            if (lastDot == -1) {
                                // No dots - what do you want to do?
                                ApplicationHelper.showToast(activity, "Please select only pdf file !!!");
                            } else {
                                extension = selectedFileUri.toString().substring(lastDot);
                                Log.e(TAG, "extension: " + extension);
                            }

                            if (extension.equals(".pdf") || mimeType.equals("application/pdf")) {
                                template_file_uri = selectedFileUri.toString();
                                displayFromUri(selectedFileUri);
                                getRealPathFromURI = ApplicationHelper.getRealPathFromURI(activity, selectedFileUri);

                            } else {
                                Log.e(TAG, "else ext: " + extension);
                                ApplicationHelper.showToast(activity, "Please select only pdf file !!!");
                                template_file_uri = null;
                            }
                            Log.e(TAG, "::::>>>getRealPathFromURI::: " + getRealPathFromURI);

                        } else {
                            Uri selectedFileUri = data.getData();
                            String path1 = getPath(activity, selectedFileUri);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    break;

                case Activity.RESULT_CANCELED:
                    template_file_uri = null;
                    break;

                default:
                    break;
            }
            break;

        default:
            break;

    }
}

getRealPathFromURI method:-

@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getRealPathFromURI(Context context, Uri uri) {
    Log.i(TAG, "getRealPathFromURI() uri " + uri);
    String pattern = "/^[ A-Za-z0-9_@./#&+-]*$/";
    uri = Uri.parse(uri.toString().replaceAll(pattern, uri.toString()));

    String path = FileUtils.getPath(context, uri);
    Log.i(TAG, "getRealPathFromURI() get path " + path);
    if (ApplicationHelper.isStringValid(path)) {
        if (!path.contains("://")) {
            path = "file://" + path;
        }
        path = path.replaceAll(pattern, path);
        //path = path.replace(" ", "%20");
    } else {
        path = uri.toString();
    }
    Log.i(TAG, "getRealPathFromURI() return path " + path);
    return path;
}

FileUtils:-

 @TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
    Log.i(TAG, "getPath() uri " + uri);
    if (DEBUG)
        Log.d(TAG + " File -",
                "Authority: " + uri.getAuthority() +
                        ", Fragment: " + uri.getFragment() +
                        ", Port: " + uri.getPort() +
                        ", Query: " + uri.getQuery() +
                        ", Scheme: " + uri.getScheme() +
                        ", Host: " + uri.getHost() +
                        ", Segments: " + uri.getPathSegments().toString()
        );

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


    if (isInternalStorageDocument(uri)) {
        return uri.toString();
    }

    // DocumentProvider
    else if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {

        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)) {

            try {
                final String id = DocumentsContract.getDocumentId(uri);
//                    final long id = Long.parseLong(DocumentsContract.getDocumentId(uri));
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                Log.e(TAG, "Uri....");
            return getDataColumn(context, contentUri, null, null);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        // 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 the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    } else if (!ApplicationHelper.haveAuthority(uri)) {
        return Constants.AUTHORITY_FILE + uri.toString();
    }

    return null;
}
Remus answered 31/12, 2018 at 11:0 Comment(9)
Can you please post a code here what you have done?Holocaust
what do you need a file path for? cannot you just use its InputStream?Paynter
Please post the code along with the stacktrace if any crash faced.Intensifier
Please check the updated question. @theapache64. I also use the InputStream but didn't get anything.Remus
Please check the updated question. @ChintakPatelRemus
i will repeat: what do you need String getRealPathFromURI and String path1 variables for?Paynter
I just use those variables to print them in Log nothing else. But everytime i get this type of format" content://com.android.providers.downloads.documents/document/157" @PaynterRemus
thats right format - it is android's Uri - dont even try to get "some real path name" as there is no such thing for a generic Uri - more herePaynter
See also https://mcmap.net/q/679200/-android-get-real-path-of-a-txt-file-selected-from-the-file-explorer/115145 and https://mcmap.net/q/1306853/-getting-the-absolute-file-path-from-content-uri-for-searched-images/115145Trillbee
H
2

Use below class file that gives File Path with just passing Uri.

and then apply as

val filePathFromUri = FilePath.getPath(this, uri)
val file = File(filePathFromUri)
val absolutePath = file.absolutePath

in your code where you get Uri in onActivityResult().

import android.annotation.TargetApi
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 java.util.*

object FilePath {
    val imageExts: ArrayList<String>
        get() {
            val imageTypes = arrayOf("png", "jpg", "jpeg", "bmp", "gif")
            val imageExts = imageTypes.indices.mapTo(ArrayList()) { imageTypes[it] }

            return imageExts
        }

    val videoExts: ArrayList<String>
        get() {
            val videoTypes = arrayOf("mpeg", "mp4", "gif", "wmv", "mov", "mpg", "3gp", "flv")
            val videoExts = videoTypes.indices.mapTo(ArrayList()) { videoTypes[it] }
            return videoExts
        }

    val docExts: ArrayList<String>
        get() {
            val docTypes = arrayOf("doc", "docx", "pdf", "txt")
            val docExts = docTypes.indices.mapTo(ArrayList()) { docTypes[it] }
            return docExts
        }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    fun getPath(context: Context, uri: Uri): String? {

        val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {

                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                val type = split[0]

                if ("primary".equals(type, ignoreCase = true)) {
                    return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
                }
            } else if (isDownloadsDocument(uri)) {

                val decodedURI = Uri.decode(uri.toString())

                if (decodedURI.contains("raw:")) {
                    return decodedURI.substring(decodedURI.indexOf("raw:") + 4)
                }

                val id = DocumentsContract.getDocumentId(Uri.parse(decodedURI))

                val contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)!!)

                return getDataColumn(context, contentUri, null, null)
            } else if (isMediaDocument(uri)) {

                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                val type = split[0]

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

                val selection = "_id=?"
                val selectionArgs = arrayOf(split[1])

                return getDataColumn(context, contentUri, selection, selectionArgs)
            }// MediaProvider
            // DownloadsProvider
        } else if ("content".equals(uri.scheme, ignoreCase = true)) {
            return getDataColumn(context, uri, null, null)
        } else if ("file".equals(uri.scheme, ignoreCase = true)) {
            return uri.path
        }// File
        // MediaStore (and general)

        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.
     */
    fun getDataColumn(context: Context, uri: Uri?, selection: String?,
                      selectionArgs: Array<String>?): String? {

        var cursor: Cursor? = null
        val column = "_data"
        val projection = arrayOf(column)

        try {
            cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
            if (cursor != null && cursor.moveToFirst()) {
                val 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.
     */
    fun isExternalStorageDocument(uri: Uri): Boolean {
        return "com.android.externalstorage.documents" == uri.authority
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    fun isDownloadsDocument(uri: Uri): Boolean {
        return "com.android.providers.downloads.documents" == uri.authority
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    fun isMediaDocument(uri: Uri): Boolean {
        return "com.android.providers.media.documents" == uri.authority
    }
}
Holocaust answered 31/12, 2018 at 11:39 Comment(1)
Can you please post an answer to Java?Wallace

© 2022 - 2024 — McMap. All rights reserved.