android - 如何在 Android Pie 中获取 pdf 文件的实际文件路径?

标签 android filepath android-version android-9.0-pie

<分区>

目前我面临无法检索 pdf 的实际文件路径的问题。我尝试了我得到的所有解决方案,但无法获得 Android Pie 中的实际文件路径。任何帮助都将不胜感激。

代码:- Intent 打开文件管理器并允许选择 pdf 文件。

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

在点击/选择任何 pdf 文件后,编译器移动到 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 方法:-

@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;
}

最佳答案

使用下面的类文件,该文件仅通过 Uri 提供文件路径。

然后申请为

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

在您的代码中,您在 onActivityResult() 中获取 Uri。

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
    }
}

关于android - 如何在 Android Pie 中获取 pdf 文件的实际文件路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53986679/

相关文章:

android - 如何解决拆分的 apk 和 bundle 的版本代码之间的冲突?

android - 调用需要 API 级别 14(当前最小值为 8): android. view.ViewGroup#canScrollHorizo​​ntally

android - java.lang.SecurityException : without permission android. permission.BIND_INPUT_METHOD 仅适用于 <=2.2

android - 在线创建文件JSON并获取URL

java - fragment 中级 (II) :Dynmically adding row in a fragment, Android

java - Android自定义View——适配不同屏幕

java - 获取当前jre的文件路径

Python pathlib.Path - 如何获取与平台无关的文件分隔符作为字符串?

java - 可以使用java从android SD卡读取文件

IIS 7.5 - 更改 management.config 文件的路径