一个但凡涉及到用户信息的应用,总少不了设置用户图像这个小功能。之前做这块的时候只是简单的复制粘贴导致最近再做这个功能的时候,却发现问题很多,拍照及相册选择后启动系统裁剪要不崩溃要不就是没有返回数据,今天好好梳理一下这个功能。
调用系统拍照界面:
private void startTakePhotoActivity() { temp_file_name = String.valueOf(System.currentTimeMillis()) + FILE_SUFFIX; temp_photo_uri = Uri.fromFile(new File(DIRECTORY, temp_file_name)); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 默认情况下不需要指定拍照生成图片的uri 系统默认返回照片缩略图uri // 如果用户指定了生成图片的uri 系统就不会返回 intent.putExtra(MediaStore.EXTRA_OUTPUT, temp_photo_uri); startActivityForResult(intent, FLAG_CAMERA); }
调用系统相册界面:
private void startPickPhotoActivity() { // temp_file_name未赋值 在这里对其初始化 temp_file_name = System.currentTimeMillis() + FILE_SUFFIX; Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); startActivityForResult(intent, FLAG_GALLERY); }
这里补充一下,很多网友都说android4.4以上怎么怎么了,其实不用想这么多,看看代码是不是还和以前没什么两样?看到有网友专门针对4.4以上版本及以下版本判断,也只是因为4.4以上版本从相册选择图片时提供另外一个意图 Intent.ACTION_OPEN_DOCUMENT ,可以使用最近浏览过的图片,代码量却大了不少。所以个人觉得就一个选择图片没必要做这么复杂,因此我还是使用相册来选图。
调用系统裁剪界面:
private void startCropPhotoActivity(Uri orgUri) { // 保存剪裁生成图片的uri String _fileName = "_" + System.currentTimeMillis() + ".jpg"; temp_photo_uri = Uri.fromFile(new File(DIRECTORY, _fileName)); // 剪裁图片意图 Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(orgUri, "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); // 将剪切的图片保存到目标Uri中 注释同拍照 intent.putExtra(MediaStore.EXTRA_OUTPUT, temp_photo_uri); intent.putExtra("return-data", false); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG); intent.putExtra("noFaceDetection", true); startActivityForResult(intent, FLAG_CROP); }
虽然代码中已经加了注释,还是要和大伙啰嗦一下上面红色加粗的代码。之前没有好好理解才导致在这里栽个大跟头。
intent.putExtra(MediaStore.EXTRA_OUTPUT, temp_photo_uri):用来指定拍照或裁剪后生成的图片存储在哪里,如果指定了这个参数,那么拍照后就不会返回生成缩略图的Uri,当然再用 intent.getData 势必会 NullPointException,这时候再要用到Uri就得从文件来或者干脆造个成员变量来保存这个Uri。
到这里问题基本上已经解决,但是现在是一个云的时代,大多对android系统个性后的ROM,相册这个功能看起来是很强大,但给开发者带来却是无尽的痛苦,接下来说说这个 云相册 引发的问题。
回到我的代码,拍照已经OK,就是从相册选择图片在 onActivityResult 返回得到 resultCode 始终为 0 (正常 RESULT_OK = -1),经过对比返回的Uri发现问题并不是大家所说的Uri格式不对,而是在测试的手机上 根本找不到选择的照片 。但为什么还显示在这里,并且选择后返回的Uri看起来和本地照片没什么区别,这些三方厂商给开发者挖了这么大个坑坑。好了,问题找到就好办了,既然是图片不存在,那我们就得让用户知道选择的这张图片不在手机上,避免了程序崩溃也提高了用户体验,如果有力气的话,完全可以不用系统的相册来选择这样就不会发生上面提到的这个问题。
说了这么多,好像废话一箩筐,针对这次出现的问题,参考了好几个网友提供的代码,里面不乏有值得我借鉴的东西,也给大伙分享一下,CameraActivity是我修改过的,在android4.4及4.1上测试通过(小米开发版ROM)。有空再封装一个工具类出来。
代码下载:http://pan.baidu.com/s/1miq120g
来源:https://www.cnblogs.com/magics/p/5323652.html