Android 4.4前后版本读取图库图片和拍照完美解决方案
转载:http://blog.csdn.net/zbjdsbj/article/details/42387551
4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了. 主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT的方法,返回的uri跟 4.3是完全不一样的,4.3返回的是带文件路径的,而4.4返回的却是 content://com.android.providers.media.documents/document/image:3951这样的,没 有路径,只有图片编号的uri.这就导致接下来无法根据图片路径来裁剪的步骤了.
来自overflow大牛的方法,4.4得到的uri,需要以下方法来获取文件的路径:
/**
* <br>功能简述:4.4及以上获取图片的方法
* <br>功能详细描述:
* <br>注意:
* @param context
* @param uri
* @return
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0]; if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
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] }; return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) { // Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
} return null;
} public 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 index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
} /**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}</span></span>
为什么会不一样呢?
Android 4.4(含)开始,通过方式访问图库后,返回的Uri如下(访问“最近”):
Uri is:content://com.android.providers.media.documents/document/image%3A18838
2 Uri.getPath is :/document/image:18838
3 对应的图片真实路径:/storage/emulated/0/Pictures/Screenshots/Screenshot_2014-09-22-21-40-53.png</span>
不但如此,对于不同类型图库,返回的Uri形式并不相同(访问普通相册):
Uri is:content://media/external/images/media/18822
2 Uri.getPath is :/external/images/media/18822
3 对应的图片真实路径:/storage/emulated/0/Download/20130224235013.jpg</span>
而4.4之前返回的Uri只存在一种形式,如下:
Uri is:content://media/external/images/media/14046
2 Uri.getPath is :/external/images/media/14046
3 对应的图片真实路径:/storage/emulated/0/DCIM/Camera/20130224235013.jpg
因此,在Android 4.4或更高版本设备上,通过简单的getDataColumn(Context, Uri, null, null)进行图片数据库已经不能满足所有需求,因此在获取图片真实路径的时候需要根据不同类型区分对待。
版本判断:
//版本比较:是否是4.4及以上版本
final boolean mIsKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
从相册选择照片方法比较:
/**
* <br>功能简述:4.4及以上从相册选择照片
* <br>功能详细描述:
* <br>注意:
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
private void SelectImageUriAfterKikat() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, SELECET_A_PICTURE_AFTER_KIKAT);
}
/**
* <br>功能简述:4.4以下从相册选照片并剪切
* <br>功能详细描述:
* <br>注意:
*/
private void cropImageUri() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 640);
intent.putExtra("outputY", 640);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(IMGPATH, TMP_IMAGE_FILE_NAME)));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection
startActivityForResult(intent, SELECT_A_PICTURE);
}
拍照通用方法,对返回数据做处理:
/**
* <br>功能简述:对拍照的图片剪切
* <br>功能详细描述:
* <br>注意:
* @param uri
*/
private void cameraCropImageUri(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/jpeg");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 640);
intent.putExtra("outputY", 640);
intent.putExtra("scale", true);
if (mIsKitKat) {
intent.putExtra("return-data", true);
} else {
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, SET_PICTURE);
}
显示等处理如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SELECT_A_PICTURE) {
if (resultCode == RESULT_OK && null != data) {
Log.i("zou", "4.4以下的");
Bitmap bitmap = decodeUriAsBitmap(Uri.fromFile(new File(IMGPATH,
TMP_IMAGE_FILE_NAME)));
mAcountHeadIcon.setImageBitmap(bitmap);
}
} else if (requestCode == SELECET_A_PICTURE_AFTER_KIKAT) {
if (resultCode == RESULT_OK && null != data) {
Log.i("zou", "4.4以上上的");
mAlbumPicturePath = getPath(MainActivity.this, data.getData());
cropImageUriAfterKikat(Uri.fromFile(new File(mAlbumPicturePath)));
}
} else if (requestCode == SET_ALBUM_PICTURE_KITKAT) {
Log.i("zou", "4.4以上上的 RESULT_OK");
Bitmap bitmap = data.getParcelableExtra("data");
mAcountHeadIcon.setImageBitmap(bitmap);
} else if (requestCode == TAKE_A_PICTURE) {
Log.i("zou", "resultCode:" + resultCode);
cameraCropImageUri(Uri.fromFile(new File(IMGPATH, IMAGE_FILE_NAME)));
} else if (requestCode == SET_PICTURE) {
Log.i("zou", "SET_PICTURE-resultCode:" + resultCode); Bitmap bitmap = null;
if (mIsKitKat) {
if (null != data) {
bitmap = data.getParcelableExtra("data");
}
} else {
bitmap = decodeUriAsBitmap(Uri.fromFile(new File(IMGPATH, IMAGE_FILE_NAME)));
}
mAcountHeadIcon.setImageBitmap(bitmap);
}
}
GIthub工程地址:https://github.com/ZBJDSBJ/CameraDemo
Android 4.4前后版本读取图库图片和拍照完美解决方案的更多相关文章
- 【转】Android 4.4前后版本读取图库图片和拍照完美解决方案
http://blog.csdn.net/zbjdsbj/article/details/42387551 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4 ...
- 【原创】Android 4.4前后版本读取图库图片方式的变化
Android 4.4前后版本读取图库图片方式的变化 本文讲述Android 4.4(KitKat)前后访问图库以及访问后通过图片路径读取图片的变化 Android 4.4(KitKat)以前 ...
- Mantis的附件图片实现预览/弹出层动画效果预览图片(LightBox2)的完美解决方案[Z]
方法1: 在Mantis的配置文件中,加入此句,将这个值设的很大,就可以直接看到图片 1 $g_preview_attachments_inline_max_size=1000000; 效果如图 这个 ...
- Android 判断软键盘弹出并隐藏的简单完美解决方案
最近项目中有一个编辑框,下面是个ListView.在触发编辑框弹出软键盘后,ListView还能滑动,并且ListView的item还能响应单击.这样的体验效果很不好.于是便想在滑动或单击item时判 ...
- 【Android】12.4 利用Intent读取图库中的图片
分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 该示例演示如何从图库(Gallery)中读取图像并用ImageView将它显示出来. 二.示例-ch1203Rea ...
- Android 简单图片浏览器 读取sdcard图片+形成缩略图+Gallery
1.读取SD卡上面的图片信息 //想要的返回值所在的列 String[] projection = { MediaStore.Images.Thumbnails._ID}; //图片信息存储在 and ...
- Android取得图库图片的具体地址
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResu ...
- 搭建Android+QT+OpenCV环境,实现“单色图片着色”效果
OpenCV是我们大家非常熟悉的图像处理开源类库:在其新版本将原本在Contrib分库中的DNN模块融合到了主库中,并且更新了相应文档.这样我们就能够非常方便地利用OpenCV实 ...
- Android外部SD卡的读取
package com.kevin.writeorreadfile1_1; import android.app.Activity; import android.bluetooth.le.ScanF ...
随机推荐
- javascript监听事件兼容
function addEvent(el ,type ,fn){ if(el.addEventListener){ el.addEventListener(type,fn,false); }else ...
- .net 网站发布 Web.Config中的<compilation debug="true"/>
Web.Config中的<compilation debug="true"/> <compilation debug="true"/> ...
- performSelector的方法
在此我对performSelector系列方法进行了总结 1. - (id)performSelector:(SEL)aSelector; - (id)performSelector:(SEL)aSe ...
- C#类型基础——学习笔记一
1.C#中的类型一共分两类,一类是值类型,一类是引用类型.2.结构类型变量本身就相当于一个实例.3.调用结构上的方法前,需要对其所有的字段进行赋值.4.所有元素使用前都必须初始化.5.(结构类型)ne ...
- hdu4006 优先队列
A - 签到 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:65768KB 64bit I ...
- C# 获取当前路径
// 获取程序的基目录.System.AppDomain.CurrentDomain.BaseDirectory F:\广告编辑系统新\taxi_edit\taxi_form\bin\Debug\ ...
- 翻译Oracle文档--SYSDBA和SYSOPER系统权限
SYSDBA和SYSOPER是管理权限,被用户来执行高级管理操作例如:创建 开启/关闭 备份/恢复 数据库.SYSDBA系统权限是针对想给予完全授权的数据库管理员SYSOPER系统权限允许一个用户执行 ...
- sqlserver查询编辑器编辑数据
1.我想编辑这几行的sortid,方式可以直接写sql,但是还有一种更简洁的方法,如下: 2.用这种方式可以直接修改,比较方便. 3.总结:要做一件事情,可能有很多种方法.而且很有可能有简单的方法,如 ...
- juqery easy ui 实现二级菜单联动
实现效果 代码: <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat= ...
- Android手机配置gcc,实现手机编译代码
1.下载gcc.zip 2.把gcc.zip解压存放在/data目录下(也可以是其他目录,看个人习惯) 3.配置gcc环境变量 export GCCHOME=/data/gcc (gcc存放路径) e ...