android根据拍摄url获取格式,Android如何通过URI获取文件路径示例代码

前言

最近在工作的过程中,遇到不同 Android 版本下 URI 采用不同方式来获取文件路径的问题。

因为需求的原因,要求拍照上传或者从相册中选择图片上传,而且图片是需要经过压缩的,大小不能超过2M。

很快,拍照的这部分就搞定了。那么相册中选择图片的也是一样的道理,应该也是轻松解决了。

至于选择图片的代码,如下所示:

intent = new Intent(Intent.ACTION_GET_CONTENT);

intent.addCategory(Intent.CATEGORY_OPENABLE);

intent.setType("image/*");

startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE);

之后就是在 onActivityResult(int requestCode, int resultCode, Intent data)中获取到 URI 。

最关键的来了,如果通过 URI 来获取文件呢?

比如,现在 URI 为 content://media/extenral/images/media/17766 ,而我们需要得到对应的文件路径。

if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {

Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);

if (cursor != null) {

if (cursor.moveToFirst()) {

int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

if (columnIndex > -1) {

path = cursor.getString(columnIndex);

}

}

cursor.close();

}

return path;

}

原以为万事大吉,但是在 Android 4.4 及以上的手机上一试,发现根本不行。因为在 Android 4.4 及以上的手机上,获取到的 URI 变成了 content://com.android.providers.media.documents/document/image%3A235700 ,和之前我们预期的不是同一种类型。

这是因为在 Android 4.4 及以上的机型,使用了 DocumentUri 来代表获取到文件的 URI 。

所以我们又要对于 DocumentUri 进行适配。

if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {

if (DocumentsContract.isDocumentUri(context, uri)) {

if (isExternalStorageDocument(uri)) {

// ExternalStorageProvider

final String docId = DocumentsContract.getDocumentId(uri);

final String[] split = docId.split(":");

final String type = split[0];

if ("primary".equalsIgnoreCase(type)) {

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

return path;

}

} else if (isDownloadsDocument(uri)) {

// DownloadsProvider

final String id = DocumentsContract.getDocumentId(uri);

final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),

Long.valueOf(id));

path = getDataColumn(context, contentUri, null, null);

return path;

} else if (isMediaDocument(uri)) {

// MediaProvider

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

path = getDataColumn(context, contentUri, selection, selectionArgs);

return path;

}

}

}

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

}

} finally {

if (cursor != null)

cursor.close();

}

return null;

}

private static boolean isExternalStorageDocument(Uri uri) {

return "com.android.externalstorage.documents".equals(uri.getAuthority());

}

private static boolean isDownloadsDocument(Uri uri) {

return "com.android.providers.downloads.documents".equals(uri.getAuthority());

}

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

}

好了,上面的代码还是容易看懂的。这下就解决了对于 Android 4.4 及以上的机型适配。顺便把以 file:// 开头的 URI 适配也补上:

if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {

path = uri.getPath();

return path;

}

完美了,下面就贴出完整的 FileUtils 代码,拿去用吧:

public final class FileUtils {

public static String getFilePathByUri(Context context, Uri uri) {

String path = null;

// 以 file:// 开头的

if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {

path = uri.getPath();

return path;

}

// 以 content:// 开头的,比如 content://media/extenral/images/media/17766

if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {

Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.Media.DATA}, null, null, null);

if (cursor != null) {

if (cursor.moveToFirst()) {

int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

if (columnIndex > -1) {

path = cursor.getString(columnIndex);

}

}

cursor.close();

}

return path;

}

// 4.4及之后的 是以 content:// 开头的,比如 content://com.android.providers.media.documents/document/image%3A235700

if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

if (DocumentsContract.isDocumentUri(context, uri)) {

if (isExternalStorageDocument(uri)) {

// ExternalStorageProvider

final String docId = DocumentsContract.getDocumentId(uri);

final String[] split = docId.split(":");

final String type = split[0];

if ("primary".equalsIgnoreCase(type)) {

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

return path;

}

} else if (isDownloadsDocument(uri)) {

// DownloadsProvider

final String id = DocumentsContract.getDocumentId(uri);

final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),

Long.valueOf(id));

path = getDataColumn(context, contentUri, null, null);

return path;

} else if (isMediaDocument(uri)) {

// MediaProvider

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

path = getDataColumn(context, contentUri, selection, selectionArgs);

return path;

}

}

}

return null;

}

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

}

} finally {

if (cursor != null)

cursor.close();

}

return null;

}

private static boolean isExternalStorageDocument(Uri uri) {

return "com.android.externalstorage.documents".equals(uri.getAuthority());

}

private static boolean isDownloadsDocument(Uri uri) {

return "com.android.providers.downloads.documents".equals(uri.getAuthority());

}

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

}

}

讲完了,讲完了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

休眠类型初学者指南

基本映射概念 学习Hibernate时&#xff0c;许多人喜欢跳到父子关联&#xff0c;而无需掌握对象关系映射的基础知识。 在开始对实体关联进行建模之前&#xff0c;了解各个实体的基本映射规则非常重要。 休眠类型 休眠类型是SQL类型和Java原语/对象类型之间的桥梁。 这些是Hibe…

fixed 语句(C# 参考)

fixed 语句禁止垃圾回收器重定位可移动的变量。fixed 语句只能出现在不安全的上下文中。Fixed 还可用于创建固定大小的缓冲区。 备注 fixed 语句设置指向托管变量的指针并在 statement 执行期间“钉住”该变量。如果没有 fixed 语句&#xff0c;则指向可移动托管变量的指针的作…

React Antd中样式的修改

如果需要对antd的样式进行修改&#xff0c; 进入你要修改的页面 注意&#xff1a;不能直接在自己的文件下面&#xff0c;加入一个css&#xff0c;修改这个class的样式&#xff0c;应该 加入global限定&#xff0c;global {} , 在{}里面写入 .classname {} 然后在设置css样式…

android /data/data/数据作用,android 清除data/data/ 下其他应用的数据

// 需在源码下编译// 实现。。。private ClearUserDataObserver mClearDataObserver;class ClearUserDataObserver extends IPackageDataObserver.Stub {public void onRemoveCompleted(final String packageName, final boolean succeeded) {/*final Message msg mHandler.ob…

使用Akka简化交易系统

我的同事正在开发一种交易系统&#xff0c;该系统可以处理大量的传入交易。 每笔交易都涵盖一种Instrument &#xff08;例如债券或股票&#xff09;&#xff0c;并且具有某些&#xff08;现在&#xff09;不重要的属性。 他们坚持使用Java&#xff08;<8&#xff09;&#…

【Python】贪心算法入门

一.引言 本文将通过两个问题和两道例题带你入门贪心算法。 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取在当前状态下最优&#xff08;最好或最有利&#xff09;的选择&#xff0c;从而希望导致全局最优解的算法。贪心算法不保证找到全局最优…

ASP.NET MVC+LINQ开发一个图书销售站点(9):编辑目录

编辑目录和新建类似&#xff0c;这里我们用MVC提供的辅助类 1.在Model 的BookShopDBDataContext分部类里添加: 2. 在CategoryController添加如下方法(注意&#xff1a;我们添加了后端验证) 3. 修改View下的EditCategory.aspx. (注意&#xff1a;我们用了MVC提供的辅助类生成Tex…

Jenkins+maven环境部署

选择使用tomcat下运行jenkins项目&#xff0c;安装步骤如下 1. 安装tomcat&#xff0c;查看想要下载的版本 https://mirrors.cnnic.cn/apache/tomcat/ wget https://mirrors.cnnic.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz 2. 安装jdk wget --no-c…

内外边距、浮动、布局相关

关于清除元素的内外边距&#xff1a; 1、行内元素只有左右边距、没有内外边距、内边距在ie6等低版本的浏览器中也会有问题。尽量不要给元素指定行内的内外边距&#xff1b; 2、外边距的合并 使用margin定义块元素的垂直外边距时&#xff0c;可能会出现外边距的合并&#xff…

android根据mac地址连接耳机,Android获取设备IMEI和Mac地址

释放双眼&#xff0c;带上耳机&#xff0c;听听看~&#xff01;public static boolean checkPermission(Context context, String permission) {boolean result false;if (Build.VERSION.SDK_INT > 23) {try {Class> clazz Class.forName("android.content.Contex…

让vs2008支持jQuery的智能提示!

告诉大家一个非常好的消息&#xff0c;就是现在我们已可以让VS2008同时支持jQuery的智能提示功能啦可以先看看下面的效果图&#xff1a;jquery1.png (18.76 K)2008-3-30 14:37:54jquery2.png (21.18 K)2008-3-30 14:37:54怎样&#xff1f;酷吧&#xff0c;呵呵想实现以上效果只…

编写干净的测试–提防魔术

很难为干净的代码找到一个好的定义&#xff0c;因为我们每个人都有自己的单词clean的定义。 但是&#xff0c;有一个似乎是通用的定义&#xff1a; 干净的代码易于阅读。 这可能会让您感到有些惊讶&#xff0c;但是我认为该定义也适用于测试代码。 使测试尽可能具有可读性是我…

Eclipse创建Java Web项目及基本配置

https://www.cnblogs.com/zzlback/p/8552622.html转载于:https://www.cnblogs.com/aiyowei/p/10428638.html

为什么要使用Vuex?

为什么要使用Vuex? 1. 假如不使用 1.1 父子组件依赖同一个state 1.2 兄弟组件依赖同一个state 2. 用了Vuex之后 3. 方便记忆和理解 更多专业前端知识&#xff0c;请上 【猿2048】www.mk2048.com

十个习惯让你精通新的开发技术

Ben Watson&#xff0c;知名开发者。任职于GeoEye&#xff0c;是其所属开发团队的领导者。本文发表于他自己的博客&#xff0c;阐述了十种学习新技术的方法。 1、要看书 在成千上万的编程图书中&#xff0c;可能很大一部分根本毫无用处。但是仍然有很多图书对你的(编程)能力有很…

基于android平台的24点游戏设计与实现需求分析,基于Android平台的24点游戏设计与实现需求分析_毕业设计论文.doc...

基于Android平台的24点游戏设计与实现摘要随着移动设备的普及以及移动设备的硬件的提升&#xff0c;移动设备的功能越来越完善&#xff0c;移动设备的系统平台也日渐火热起来。目前国内最常见的移动开发平台有Symbian&#xff0c;iPhone&#xff0c;Windows Phone以及当下正在逐…

序列化代理模式示例

有些书可以极大地改变您的生活。 其中一本是Joshua Bloch撰写的“ Effective Java” 。 在下面您可能会发现一些小的实验&#xff0c;该实验的灵感来自于本书的第11章“串行化”。 假设我们有一个为继承而设计的类&#xff0c;它本身不是可序列化的 &#xff0c;并且没有无参数…

fit_transform和transform的区别

部分转载 https://blog.csdn.net/weixin_38278334/article/details/82971752 https://www.cnblogs.com/summer-nude/p/7380694.html 写在前面fit和transform没有任何关系&#xff0c;仅仅是数据处理的两个不同环节&#xff0c;之所以出来fit_transform这个函数名&#xff0c;仅…

使用注解配置Spring

使用注解配置Spring 1.为主配置文件引入新的命名空间(约束) 2.开启使用注解代理配置文件 3.在类中使用注解完成配置 将对象注册到容器 修改对象的作用范围 值类型注入 引用类型注入 注意: 初始化|销毁方法 转载于:https://www.cnblogs.com/HiJackykun/p/10428728.html

android监控指纹信息变化,android监听指纹变化(解决反射思路在android10不生效的问题)...

前天偶尔运行代码&#xff0c;一个段异常映入眼帘&#xff0c;我擦android10上反射机制监听不到指纹id等数据了&#xff0c;原因是android10彻底抛弃了之前指纹的api。所以反射不到了。怎么解决这个问题&#xff1f;我们换个思路当然反射依然可以&#xff0c;不过你需要在andro…