前言

最近在工作的过程中,遇到不同 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());

}

}

讲完了,讲完了。

总结

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

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

  1. java 如何导出json文件_java导出json格式文件的示例代码

    本文介绍了java导出json格式文件的示例代码,分享给大家,具体如下: import java.io.File; import java.io.FileWriter; import java.io. ...

  2. Python语言学习:创建/删除文件/文件夹、获取当前文件/文件夹路径(系统环境路径/目录)、获取当前文件夹下的所有子文件路径等代码(os系列用法)实现之详细攻略

    Python语言学习:创建/删除文件/文件夹.获取当前文件/文件夹路径(系统环境路径/目录).获取当前文件夹下的所有子文件路径等代码(os系列用法)实现之详细攻略 目录 系统环境路径的设置 1.sys ...

  3. android使用的图片压缩格式,Android 之使用libjpeg压缩图片

    一.环境 Android Studio 4.0.1 NDK R15c so包是2.0.6生成的 libturbojpeg.so 二.准备 1.编写native方法并用javah命令生成头文件 obje ...

  4. android自定义push通知_android通过自定义toast实现悬浮通知效果的示例代码

    android通过toast实现悬浮通知效果,如图: 实现的功能: 自定义悬浮弹窗: 点击其他地方该布局不受影响: 可自定义显示时间: 可以设置点击事件: 代码如下: import android.c ...

  5. android镜像文件怎么命名,android镜像文件说明(示例代码)

    android 源码编译完成后会生成三个镜像文件 system.img ->yaffs2格式 userdata.img ->yaffs2格式 ramdisk.img ->cpio 前 ...

  6. 《阿里巴巴Android开发手册》v1.0.1更新,优化部分内容和示例代码

    摘要: 春节余味尚未消,我们为移动开发者准备了一份迟到的新年礼物--<阿里巴巴Android开发手册>,继<阿里巴巴Java开发手册>之后,阿里巴巴开发规范家族又添一丁,「阿里 ...

  7. Android安卓的APP应用安装后该应用所有相关文件路径

    一. Android应用安装后该应用所有相关文件路径有4种情况: system/app 系统自带的应用程序,无法删除.root后可以删除,注意可能造成系统崩溃,不过有的垃圾捆绑软件只能这么删除了 da ...

  8. android仿钉钉日程日历,Flutter仿钉钉考勤日历的示例代码

    本文主要介绍了Flutter仿钉钉考勤日历的示例代码,分享给大家,具体如下: 效果 原型 开发 1. 使用 // 考勤日历 DatePickerDialog( initialDate: DateTim ...

  9. java bitmap获取图片大小_android 通过uri获取bitmap图片并压缩

    很多人在调用图库选择图片时会在onActivityResult中用Media.getBitmap来获取返回的图片,如下: Uri mImageCaptureUri = data.getData(); ...

最新文章

  1. python能做游戏吗-python能做游戏吗
  2. 弱口令的分析和爆破工具使用
  3. UIProgressView的使用
  4. JupyterNotebook随记(part1)--打开默认目录
  5. 什么叫pin脚的pad_为什么特小尺寸液晶屏价格比较高
  6. 小demo, java swing窗口编程(JDK 1.6)
  7. spark SQL(三)数据源 Data Source----通用的数据 加载/保存功能
  8. 中学数字化实验室建设及配置要求
  9. 用MATLAB 读写各种文件 ∈ Matlab 使用笔记
  10. android开发用什么字体,移动端web app和页面开发使用什么字体?微软雅黑?
  11. 优秀的音频EQ均衡器音效源码
  12. jmeter使用心得(一)
  13. 从链家爬取北京各区二手房房价进行分析并实现数据可视化
  14. C++函数传参int a,int *a,int a,const int a的区别
  15. 简单的从中国植物志爬去植物拉丁文名的代码(PHP)
  16. provider: SQL Network Interfaces, error: 26 - 定位指定的服务器/实例时出错
  17. 暴力搜索算法浅显易懂
  18. .NET B/S工作的基本流程
  19. 获新轮10亿融资,“诗人小冰”又get哪些超强新技能?
  20. 云服务器相比传统IDC有哪些优势?这里讲得很清楚了

热门文章

  1. window下查看dll, lib文件是32位还是64位
  2. 汉中计算机培训班学费是多少,汉中远程教育培训班收费多少
  3. [MySQL]经常无故崩溃amd.dll , boot1.exe病毒
  4. 前端程序员书桌上不可缺少的CSS书籍
  5. 少儿编程100讲轻松学python(一)-python怎么打开
  6. 远程修改linux文件内容,用VS Code连接远程Linux服务器实时修改代码
  7. eureka 集群失败的原因_eureka集群中的疑问?
  8. mysql运算结果放入表中_MySQL表1新增数据,计算开始、结束日期之间所有时间,插入到表2中...
  9. 【APICloud系列|20】如何使用使用APICloud开发出优质的Hybrid App
  10. Mysql身份认证漏洞及利用(CVE-2012-2122)