【问题标题】:Android: Files: Unable to get file path from content URI when file is selected from RECENT section in file browserAndroid:文件:从文件浏览器的最近部分选择文件时,无法从内容 URI 获取文件路径
【发布时间】:2020-04-22 02:26:33
【问题描述】:

我试图从 data.data 给出的 Uri 中获取文件路径!! android 中的 onActivityResult() 方法。当我在文件浏览器中选择 DCIM 文件夹时,我能够获取文件路径,但是当我从文件浏览器的 RECENT 部分中选择相同的文件时,我没有获取文件路径。

按钮点击代码:

                                        val intent = Intent();
                                        intent.setType("image/*");
                                        val mimeTypes: Array<String> = arrayOf("image/*", "application/pdf")
                                        intent.putExtra(Intent.EXTRA_MIME_TYPES,mimeTypes)
                                        intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
                                        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                        startActivityForResult(Intent.createChooser(intent, "Select File"), 101);

onActivityResult()方法返回数据的代码:

var selectedImagePathFB:String = ""
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == RESULT_OK) {
        if (requestCode == 101) {
            val selectedImageUri:Uri = data?.data!!
            selectedImagePathFB = getPath(this@MyContactUsActivity,selectedImageUri);
            //selectedImagePathFB = AppUtils().getRealPathFromURI(this@MyContactUsActivity,selectedImageUri)
            val url: String = selectedImagePathFB

        }
    }
}

getPath(Context,Uri) 是 paulburke 从 stackoverflow 中常见的代码:

 public static String getPath(final Context context, final Uri uri) {


    // DocumentProvider
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {

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

            return Environment.getExternalStorageDirectory() + "/" + split[1];

            // TODO handle non-primary volumes
        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {
            try {
                final String id = DocumentsContract.getDocumentId(uri);
                //Log.d(TAG, "getPath: id= " + id);
                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            }catch (Exception e){
                e.printStackTrace();
                List<String> segments = uri.getPathSegments();
                if(segments.size() > 1) {
                    String rawPath = segments.get(1);
                    if(!rawPath.startsWith("/")){
                        return rawPath.substring(rawPath.indexOf("/"));
                    }else {
                        return rawPath;
                    }
                }
            }
        }
        // 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();
    }

    return null;
}
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);
        }
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if (cursor != null)
            cursor.close();
    }
    return "nodata";
}

public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}

public static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

我正在 android Q 设备上进行测试。为什么在文件浏览器中从 RECENT 部分选择文件时,我没有得到任何文件路径,同时在 STORAGE 部分中选择相同的文件正在返回文件路径?如果不是来自文件路径,是否还有一种解决方法可以转换 Base64 字符串中的 PDF 或图像等文件?

【问题讨论】:

  • 完成,缺少 WRITE_EXTERNAL_STORAGE 的运行时权限。

标签: android file android-contentprovider


【解决方案1】:

根据您的代码,没有错误。但是您必须先获得存储权限,然后才能从“最近”部分获取文件。需要读取和写入权限。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多