本文转载自:http://www.jianshu.com/p/f9a63fcc0b91

起因

Android在4.4之后的版本(包括4.4)中,从相册中选取图片返回Uri进行了改动。所以我们无法通过该Uri来取得文件路径,从而解码图片,将其显示出来。

在4.3或以下可以直接用Intent.ACTION_GET_CONTENT打开相册;在4.4或以上,官方建议用ACTION_OPEN_DOCUMENT打开相册

4.4之前的版本

在4.4之前的版本,返回的Uri如下:content://media/external/images/media/8302

我们可以通过ContentResolver的查询方法来获取路径:

Uri uri = "content://media/external/images/media/8302";
String imagePath = getImagePath(uri, null);
private String getImagePath(Uri uri, String selection) {String path = null;Cursor cursor = getContentResolver().query(uri, null, selection, null, null);if (cursor != null) {if (cursor.moveToFirst()) {path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));}cursor.close();}return path;}

代码分析,当我们通过uri得到了相册数据库图片的表,然后通过索引MediaStore.Images.Media.DATA获取所得行的"_data"列的值。这样我们就得到了具体的文件路径,可以通过创建输入流来获取相应的Bitmap,并进行显示。

4.4之后的版本,包括4.4

在4.4之后的,包括4.4的版本,返回的Uri有可能是以下的一种:

  • content://com.android.providers.media.documents/document/image%3A8302
  • content://com.android.providers.downloads.documents/document/5
  • content://media/external/images/media/8302

我们不能直接通过前两种Uri直接获取到对应的表,所以需要"翻译一下":

private void handleImageOnKitKat(Intent data) {String imagePath = null;Uri uri = data.getData();if (DocumentsContract.isDocumentUri(this, uri)) {String docId = DocumentsContract.getDocumentId(uri);if ("com.android.providers.media.documents".equals(uri.getAuthority())) {//Log.d(TAG, uri.toString());String id = docId.split(":")[1];String selection = MediaStore.Images.Media._ID + "=" + id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {//Log.d(TAG, uri.toString());Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri, null);}} else if ("content".equalsIgnoreCase(uri.getScheme())) {//Log.d(TAG, "content: " + uri.toString());imagePath = getImagePath(uri, null);}}

代码分析:

判断步骤:

  1. 首先对Uri的authority进行判断。是document类型的Uri还是普通的media类型的Uri。
  2. 由于document类型有两种:media和download类型,所以需要进一步判断。因为这里涉及Uri的id部分不同。
  3. 如果是普通类型,那么和4.4之前的处理完全一样。可以直接通过Uri获取文件路径。

如果是media类型的document Uri,我们首先通过DocumentsContract.getDocumentId(uri);获取到"image%3A8302"。然后通过String.split方法来获取真正的id。

这里为什么用":"来作为分隔符我也不是很清楚...而且还学到一个东西ContentResolver.query()方法中selection参数可以不用占位符"?"直接获取指定想要的列。

MediaStore.Images.Media._ID指的是我们获取到指定image文件的id在表中的列名。MediaStore.Images.Media.EXTERNAL_CONTENT_URI则是相册图片表真正的标示符。

这里的Uri获取是通过打开相册选定图片后,返回的Intent中获取的。

当我们获取到选中图片真正的Uri后,就可以通过之前的getImagePath()方法来获取表中的文件路径。最终达到解码图片的目的。

参考

Android 4.4从图库选择图片,获取图片路径并裁剪

Android-Uri To Path

《第一行代码》

Android Uri to Path相关推荐

  1. Android Uri 转 Path

    文件管理器的组成 调用系统自带的文件管理器有如下几个选项,分为两类 系统自带的文件管理器 第三方集成到系统管理器中 下面是调用选择文件方法后,调用系统文件管理器出来的界面 网上可以搜到很多 Uri 转 ...

  2. Android中Uri和Path之间的转换

    Android Uri to Path 现在遇到的常规Uri有两种: 媒体文件的Uri是content://, 表示这是一个数据库数据.去数据库查询正常返回 其他的文件Uri是file://, 表示这 ...

  3. Android中Uri 和Path之间的相互转化

    Android Uri to Path 现在遇到的常规Uri有两种: 媒体文件的Uri是content://, 表示这是一个数据库数据.去数据库查询正常返回. 其他的文件Uri是file://, 表示 ...

  4. android 本地地址转换为url,android本地mipmap图片转url、绝对路径转URL URL URI File Path 转换...

    标签: url uri file path File to URI: File file = ...; URI uri = file.toURI(); File to URL: File file = ...

  5. Android中Uri和path file三者的相互转换

    一.path转file File file = new File(path); 二.path转uri Uri uri = Uri.parse(path); 三.uri转path /*** 将URI路径 ...

  6. Android自定义控件系列--Path综述

    Android自定义控件系列–Path综述 项目源码 点击查看详情 Path 中文 释义为路径 然而它在自定义控件中却有着神一样的着色,这个神,是创造神奇效果的意思 1 Path 的创建 Path p ...

  7. Tomcat启动报异常:com.sun.org.apache.xerces.internal.util.URI$MalformedURIException: Path contains invalid

    报错 com.sun.org.apache.xerces.internal.util.URI$MalformedURIException: Path contains invalid characte ...

  8. Android URI简介

    就Android平台而言,URI主要分三个部分:scheme, authority and path.其中authority又分为host和port.格式如下: scheme://host:port/ ...

  9. android uri图片压缩,详解android 通过uri获取bitmap图片并压缩

    详解android 通过uri获取bitmap图片并压缩 很多人在调用图库选择图片时会在onactivityresult中用media.getbitmap来获取返回的图片,如下: uri mimage ...

最新文章

  1. 深入DataGrid分页样式实例
  2. Tomcat学习总结(3)——Tomcat优化详细教程
  3. php socket的一些问题
  4. centos7下memcached的安装配置
  5. HDU2024 C语言合法标识符【入门】
  6. RTN实时音视频传输网络
  7. 爬虫 (7)—— 爬取网络小说,详细分析及代码
  8. linux网桥动态ip,使用Linux主机当网桥
  9. SDN(一) 用OpenWRT将路由器刷成openflow交换机
  10. matlab 共振峰检测,基于matlab的语音共振峰的估计.doc
  11. 中国科技大学科学岛计算机系,招生信息 | 中国科学技术大学科学岛优秀大学生夏令营通知...
  12. 【Book 133】Illuminate-Harness the Positive Power of negative Thinking
  13. 模拟生态圈_模拟器之争 夜神构建手游PC化生态圈
  14. 将N个整数按从小到大排序的冒泡排序法是这样工作的:从头到尾比较相邻两个元素,如果前面的元素大于其紧随的后面元素,则交换它们。通过一遍扫描,则最后一个元素必定是最大的元素。然后用同样的方法对前N−1个元
  15. 毕业设计-基于微信小程序的校园快递代取系统
  16. html 多个插件,webpack中html-webpack-plugin插件的使用(生成多个html页面,引入不同的js文件)...
  17. 学生管理系统(C++语言_顺序表)
  18. PHP设计模式系列:目录
  19. 软件开发项目保密协议
  20. Java单元测试介绍

热门文章

  1. jquery 控制frameset frame节点内容(在子窗口中把该窗口中的焦点处的text内容填
  2. netsh命令使用详解
  3. 问题二十四:怎么模拟ray tracing图形中介质材料的颜色(dielectric)
  4. 大数据分析平台具备什么功能特点
  5. 数据挖掘有哪些主要步骤
  6. 大数据存在的安全隐患该如何防患
  7. 如何破解物联网卡带来的连接痛点
  8. oracle数据泵能增量吗,Oracle12c中数据泵新特性之功能增强(expdp, impdp)
  9. 用Matlab搭建GUI视频处理工具
  10. 耐克人脸识别_人脸识别首案宣判,当人脸识别遇上面试,将碰出怎样的火花?...