android百度路径规划简书,Android Uri to Path

起因

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有可能是以下的一种:

我们不能直接通过前两种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);

}

}

代码分析:

判断步骤:

首先对Uri的authority进行判断。是document类型的Uri还是普通的media类型的Uri。

由于document类型有两种:media和download类型,所以需要进一步判断。因为这里涉及Uri的id部分不同。

如果是普通类型,那么和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()方法来获取表中的文件路径。最终达到解码图片的目的。

实际效果

f9a63fcc0b91

Uri To Path.gif

参考

《第一行代码》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值