代码已上传到我的github上https://github.com/LuJN/ChoosePicTest
case CHOOSE_PHOTO:
// 判断手机系统版本号
if(Build.VERSION.SDK_INT >= 19) {
// 4.4及以上系统使用这个方法处理图片
handleImageOnKitKat(data);
} else {
// 4.4以下系统使用这个方法处理图片
handleImageBeforeKitKat(data);
}
break;
大家看一下这段从相册中选择照片的代码,发现这里需要判断系统版本号,根据系统版本号来使用不同的方法,下面我们来看一下这两个方法都做了什么
先来看一下4.4以下系统的方法handleImageBeforeKitKat(data)
private void handleImageBeforeKitKat(Intent data) {
Uri uri = data.getData();
String imagePath = getImagePath(uri, null);
displayImage(imagePath);
}
很简单,就是根据uri来获得图片的路径
下面来看一下4.4以上系统(包括4.4)的方法handleImageOnKitKat(data)
@TargetApi(Build.VERSION_CODES.KITKAT)
private void handleImageOnKitKat(Intent data) {
String imagePath = null;
Uri uri = data.getData();
if(DocumentsContract.isDocumentUri(this, uri)) {
// 如果是document类型的Uri,则通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
if(uri.getAuthority().equals("com.android.providers.media.documents")) {
String id = docId.split(":")[1];// 解析出数字格式的id
String selection = MediaStore.Images.Media._ID + " = " + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
} else if(uri.getAuthority().equals("com.android.providers.downloads.documents")) {
Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
} else if(uri.getScheme().equalsIgnoreCase("content")) {
// 如果不是document类型的Uri,则使用普通方式处理
imagePath = getImagePath(uri, null);
}
displayImage(imagePath);// 根据图片路径显示图片
}
哇,是不是发现比4.4以下系统的代码多了很多,这是为什么呢??
之所以要这么做,是因为Android系统从4.4版本开始,选取相册中的图片分两种情况:返回图片真正的Uri,返回一个封装过的Uri,因此如果是4.4版本以上的手机就需要判断返回的uri是否是封装的Uri,如果是就需要对这个Uri进行解析才行。大家看下图。这就是从相册中选区照片的效果图。(华为手机)
当我们从最近、图片、下载内容中选取照片时返回的Uri是封装的Uri,我们必须进行解析
当我们从图库、文件管理中选取照片时返回的Uri是图片真正的Uri,我们不需要解析,像4.4以下系统那样处理就行了
其实之所以会有以api19为界限是因为我们用了Intent.ACTION_GET_CONENT这个action,我们可以换成Intent.ACTION_PICK,这样就不用以api19为界限了
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_PHOTO);
这是我们启动从相册中获取图片的代码
如果我们将启动代码换成如下
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, CHOOSE_PHOTO);
这就是启动效果图,直接打开了图库,没有前面效果图复杂,无论是api19以下还是以上,返回的Uri都是图片真正的Uri