首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在android 11中从Uri获取真实路径

在Android 11中,由于隐私和安全的考虑,无法直接从Uri获取真实路径。Android 11引入了Scoped Storage机制,限制了对外部存储的访问权限。但是,我们仍然可以通过以下方法获取Uri对应文件的真实路径:

  1. 使用ContentResolver查询Uri获取文件的真实路径:
代码语言:txt
复制
public String getRealPathFromUri(Context context, Uri uri) {
    String filePath = "";
    if (uri.getScheme().equals("content")) {
        Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                filePath = cursor.getString(index);
            }
            cursor.close();
        }
    } else if (uri.getScheme().equals("file")) {
        filePath = uri.getPath();
    }
    return filePath;
}
  1. 使用DocumentFile获取Uri对应文件的真实路径:
代码语言:txt
复制
public String getRealPathFromUri(Context context, Uri uri) {
    String filePath = "";
    if (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)) {
                filePath = Environment.getExternalStorageDirectory() + "/" + split[1];
            }
        } else if (isDownloadsDocument(uri)) {
            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.parseLong(id));

            filePath = getDataColumn(context, contentUri, null, null);
        } 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]};

            filePath = getDataColumn(context, contentUri, selection, selectionArgs);
        }
    } else if ("content".equalsIgnoreCase(uri.getScheme())) {
        filePath = getDataColumn(context, uri, null, null);
    } else if ("file".equalsIgnoreCase(uri.getScheme())) {
        filePath = uri.getPath();
    }
    return filePath;
}

private 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 index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(index);
        }
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    return "";
}

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

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

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

这两种方法可以根据Uri的不同类型进行处理,从而获取到文件的真实路径。需要注意的是,由于Android 11的限制,某些Uri可能无法直接获取真实路径,此时可以考虑使用文件流进行操作,而不是依赖于真实路径。

推荐的腾讯云相关产品:腾讯云对象存储(COS),提供了安全可靠、高扩展性的云端存储服务,适用于存储、备份、归档、大数据分析等场景。产品介绍链接地址:https://cloud.tencent.com/product/cos

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

16分8秒

人工智能新途-用路由器集群模仿神经元集群

领券