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;// DocumentProviderif (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {// ExternalStorageProviderif (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];}}// DownloadsProviderelse 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);}// MediaProviderelse 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 addressif (isGooglePhotosUri(uri))return uri.getLastPathSegment();return getDataColumn(context, uri, null, null);}// Fileelse 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());
}

为什么会不一样呢?

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

不但如此,对于不同类型图库,返回的Uri形式并不相同(访问普通相册):

Uri is:content://media/external/images/media/18822
2 Uri.getPath is :/external/images/media/18822
3 对应的图片真实路径:/storage/emulated/0/Download/20130224235013.jpg

而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);  }

4.4及以上选取照片后需要调用剪切方法:

/** * <br>功能简述: 4.4及以上选取照片后剪切方法* <br>功能详细描述:* <br>注意:* @param uri*/
private void cropImageUriAfterKikat(Uri uri) {Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "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", true); //返回数据bitmapintent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true); // no face detectionstartActivityForResult(intent, SET_ALBUM_PICTURE_KITKAT);
}

拍照通用方法,对返回数据做处理:

/**
* <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前后版本读取图库图片和拍照完美解决方案相关推荐

  1. 【转】Android 4.4前后版本读取图库图片和拍照完美解决方案

    http://blog.csdn.net/zbjdsbj/article/details/42387551 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4 ...

  2. Android基于红米系列手机读取本地图片路径失败的解决方案

    最近 公司的项目上有 扫描二维码功能,当然必不可少的就会有读取本地二维码需求.首先就是跳转到本地相册,如下代码: /*** show images in the android device medi ...

  3. Android判断软键盘弹出并隐藏的简单完美解决方案

    Android判断软键盘弹出并隐藏的简单完美解决方案 参考文章: (1)Android判断软键盘弹出并隐藏的简单完美解决方案 (2)https://www.cnblogs.com/thare1307/ ...

  4. 【项目中】Android 小米红米手机无法读取照片图片路径的问题

    前两天在项目中实现了可本地选择照片的功能,今天同事告诉我他的小米手机没有办法选择照片,点击选中的照片后总是无法将照片传入到应用内,而在选择图片页面选择"本地",就可以成功选择照片和 ...

  5. Android中遇到button按钮设置背景图片无法显示的解决方案

    给button设置了background的属性却显示不出来 1.在图片导入时选错位置,应该选择第一个位置,如果选了第二个图片后面会有(v24)[如下图]就有可能加载不出来.  新版引入drawable ...

  6. Flutter-选取图库图片和拍照功能,选取视频和拍摄视频

    1.先引入库image_picker 2.功能代码 import 'package:flutter/cupertino.dart'; import 'package:flutter/material. ...

  7. html背景图实现虚线,去掉a标签和按钮加背景图片虚线/阴影完美解决方案

    当用户注册都会点击一个a标签更换验证码.当点击后a标签上有个阴影部分.对于喜欢美观的同学却不可容忍! 这是什么原因呢?原来是a标签的href属性惹的祸. 1.仅仅是a标签 我了解的有两种解决办法 其一 ...

  8. Android端h5不能选择图片,weui公众号开发h5部分手机不能选择图片及拍照问题

    在使用weui采用h5进行公众号开发时,input file选择图片控件,在部分安卓手机不能拍照.不能选择图片. 经过创软公众号开发团队分析,将input代码设置如下方式即可选择图片或者拍摄图片,成功 ...

  9. android读取外部图片,Android读取本地图库与调用摄像头拍摄

    本文主要介绍如何读取Android本地图库的图片以及调用安卓的摄像头进行拍摄. 一.布局 布局比较简单,MainActviivty的布局文件只有两个按钮,一个是读取图库的,另一个是打开摄像头的,另外R ...

最新文章

  1. 搭建php帮助中心,帮助中心
  2. 2018上C语言程序设计(高级)作业-第1次作业
  3. c语言二叉排序树的创建与查找,C语言实现二叉查找树的插入和删除操作问题求教...
  4. Eclipse安装SVN插件方式简明介绍
  5. Teams的MessageExtension最新功能:Initiate actions
  6. LeetCode算法入门- Reverse Integer-day6
  7. 对POSIX和SystemV消息队列优化:用户态消息队列
  8. C++_类和对象_C++多态_纯虚函数和抽象类---C++语言工作笔记072
  9. 解决: Android.bp ninja: error: unknown target MODULES-IN-xxx报错
  10. python字典常见操作
  11. scratch课程案例——漫天飞雪
  12. HTML5期末考核大作业,网站——旅游景点。 学生旅行 游玩 主题住宿网页
  13. 网易游戏再出新招:探索人脸识别功能
  14. ubuntu 18.04 英伟达显卡驱动
  15. PyTorch之分布式操作中的Barrier
  16. 创建视图时插入自增id
  17. 我是一个搞IT的农民工
  18. 走进音视频的世界——杜比视界Dolby Vision与HDR
  19. JS实现JSON.stringify
  20. CVPR 2020 Modality Shifting Attention Network for Multi-modal Video Question Answering

热门文章

  1. linux批量拷贝文件脚本,把文件复制N份的2个Shell脚本代码
  2. 下载centos下的工具包
  3. 【物联网学习笔记——人人学IoT系列】三、窄带无线,海量物联
  4. SQL注入绕过安全狗
  5. Echarts通过svg画扇形例子,含矩形、三角形等
  6. 计算机毕业设计Node.js+Vue酒店住房管理系统(程序+源码+LW+部署)
  7. 数组降序排列_Javase基础部分:数组排序(冒泡排序)(含视频讲解)
  8. python中使用scipy.integrate求积分、二重积分、三重积分
  9. python函数和类的区别_python-函数、类与对象
  10. 墨墨背单词快捷键失灵