首页
学习
活动
专区
工具
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

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

相关·内容

Android如何通过URI获取文件路径示例代码

前言 最近在工作的过程中,遇到不同 Android 版本下 URI 采用不同方式来获取文件路径的问题。...因为需求的原因,要求拍照上传或者相册中选择图片上传,而且图片是需要经过压缩的,大小不能超过2M。 很快,拍照的这部分就搞定了。那么相册中选择图片的也是一样的道理,应该也是轻松解决了。...最关键的来了,如果通过 URI获取文件呢? 比如,现在 URI 为 content://media/extenral/images/media/17766 ,而我们需要得到对应的文件路径。...因为在 Android 4.4 及以上的手机上,获取到的 URI 变成了 content://com.android.providers.media.documents/document/image%3A235700...这是因为在 Android 4.4 及以上的机型,使用了 DocumentUri 来代表获取到文件的 URI 。 所以我们又要对于 DocumentUri 进行适配。

3.8K00

Android应用中是怎么调用系统相册中的照片的

我们知道在安卓4.4以后是不能把文件的真实路径直接给别的应用的,所以返回的uri是经过封装的,所以我们要进行解析取出里面的路径。...content类型的uri通过getImagePath这个方法来获取真实路径真实路径通过displayImage这个方法就可以展示出来了。所以主要的工作就是怎么拿到真实路径。...不了解的读者可以查看这篇博客Android中的Cursor。然后通过这个Cursor对象的MediaStore.Images.Media.DATA这个参数就可以获取真实路径了。...类型的uri或者真实路径的String。...首先是版本低于4.4的,因为返回的是真实uri,也就是content开头的那个,所以直接通过getImagePath获取真实路径再通过displayImage展示即可。

2.4K20

Android应用中是怎么调用系统相册中的照片的

我们知道在安卓4.4以后是不能把文件的真实路径直接给别的应用的,所以返回的uri是经过封装的,所以我们要进行解析取出里面的路径。...content类型的uri通过getImagePath这个方法来获取真实路径真实路径通过displayImage这个方法就可以展示出来了。所以主要的工作就是怎么拿到真实路径。...不了解的读者可以查看这篇博客Android中的Cursor。然后通过这个Cursor对象的MediaStore.Images.Media.DATA这个参数就可以获取真实路径了。...类型的uri或者真实路径的String。...首先是版本低于4.4的,因为返回的是真实uri,也就是content开头的那个,所以直接通过getImagePath获取真实路径再通过displayImage展示即可。

85220

手机打开照相机_安卓11调用第三方相机

android:layout_gravity="center_horizontal" /> 获取控件并绑定事件 @Override protected void onCreate(Bundle...} //判断系统版本,低于7.0会将file对象转换为uir对象否则调用getUriForFile将file对象转化为一个封装过的uir对象 //因为7.0开始直接使用本地真实路径会被认为是不安全的会抛出...Uri,直接获取图片路径即可 imgPath = uri.getPath(); } displayImage(imgPath);//显示选中的图片 } private void handleImageOnKiKat...; //通过 Uri 和 selection 来获取真实的图片路径 Cursor cursor = getContentResolver().query(uri, null, selection, null...发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

1.2K20

targetSdk27 FileProvider 摄像和照相

拓展:获取图片方式 4.1 通过绝对路径获取图片 4.2 通过Uri获取资源流 4.3 通过cursor获取图片 相机 以下,调用相机的代码出自开源项目 SelectImgAsWechath 。...而 Android N 开始,将不允许在 App 间,使用 file:// 的方式,传递一个 File ,否者会抛出 FileUriExposedException的错误,会直接引发 Crash。...当我们代码中使用的绝对路径,( “DCIM/camerademo”)匹配到了install.mxl中设置到的path字段的内容(path=“DCIM/camerademo”),Uri中显示路径就会被对应的...拓展:获取图片方式 4.1 通过绝对路径获取图片 image.setImageBitmap(BitmapFactory.decodeFile(takeImageFile.getAbsolutePath(...和selection来获取真实路径 Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,并且提供了一套数据库表格,通过Content Provider

84910

Android | 作用域存储适配

,将 File 转换成 Uri 对象,这个 uri 对象表示这本地真实路径。...复制代码 ​ 在 7.0 后,这种通过真实路径获取Uri 被认为是不安全的,所以提供了一种新的解决方案,就是通过 FileProvide 来实现文件的访问,FileProvider 是一种比较特殊的内容提供器...就是 Android 系统对 SD 卡做了很大的限制, 10.0 开始,每个程序只能有权在自己的外置存储空间关联的目录下读取和创建相应的文件,也称作沙箱。...获取改目录的代码是:getExternalFilesDir() ,关联的目录路径大致如下: /storage/emulated/0/Android/data//files 复制代码 ​ 将数据放在这个目录下...,需要注意的是:共享文件夹可以通过 uri 进行访问,拿到输入/输出流等。

68120

App磁盘沙盒工具实践

:/sdcard/Android/data/com.yc.helper 第三种:其它目录 比如各个App在/sdcard/目录下创建的目录,支付宝创建的目录:alipay/,高德创建的目录:amap...,通过MediaStore获取Uri。...路径可以直接构造也可以通过MediaStore获取。 2、通过Uri访问。Uri可以通过MediaStore或者SAF(存储访问框架,通过intent调用startActivity访问)获取。...如下所示,下面构造后,第三方应用收到此Uri后,并不能从路径看出我们传递的真实路径,这就解决了第一个问题。...//如此构造后,第三方应用收到此Uri后,并不能从路径看出我们传递的真实路径,这就解决了第一个问题: //发送方传递的文件路径接收方完全知晓,一目了然,

1.6K30

Android调用系统照相机拍照与摄像的方法

类型,现有的相机应用中请求一张图片。...设置系统现有相机应用的拍摄照片的保存路径,需要用Intent.putExtra()方法通过MediaStore.EXTRA_OUTPUT去设置Intent的额外数据,这里传递的是一个Uri参数,可以是一个文件路径的..., uri); 3、获取系统现有相机拍摄的图片   在新开启的Activity中,如果需要获取它的返回值,则需要使用startActivityForResult(Intent,int)方法开启Activity...在Demo中,有两个Button分别以指定路径的方式和不指定路径的方式启动系统相机,并获取返回值显示到ImageView中,Demo中注释比较详细,这里不再累述了。...5、系统现有相机拍摄视频   系统现有的相机应用中获取拍摄的视频,与获取拍摄的图片过程大致相同,但是它除了可以通过putExtra()设置MediaStore.EXTRA_OUTPUT输出路径外,还可以设置其它值

6.6K21

Android开发中,怎样调用摄像机拍照以及怎样本地图库中选取照片

@TargetApi(19) private void handleImageOnKitKat(Intent data) { //其实这个方法的目标很简单,就是要获取图片的真实路径...我们获取的图片uri不是真实的图片uri,是封装过的,不能直接用来显示图片,我们要进行解析 Uri uri = data.getData();//通过传入intent参数来获取信息,图片的内容...//进行数据库查询是作为参数,主要是约束我们的查询条件 //getImagepath()方法是我们自己提供的用来获取图片真实路径...displayImage(imagepath); } //获取图片路径的方法 private String getImagepath(Uri...uri, String selection) { String path = null; //通过uri和selection获取真实的图片路径 //其实selection

59830
领券