Android 7.0拍照与照片裁剪
2018-02-02 16:15
211 查看
在android系统7.0以上时,调用手机拍照功能会出现如下错误:
1、android.os.FileUriExposedException:file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg exposed beyond app through ClipData.Item.getUri() 2、android.os.FileUriExposedException:file:///storage/emulated/0/DCIM/RxGalleryFinal/IMG_20161018180127.jpg exposed beyond app through Intent.getData()
出现以上错误的原因:
主要是由于在Android 7.0以后,用了Content Uri 替换了原本的File Uri,故在targetSdkVersion=24的时候,部分 “`Uri.fromFile()“` 方法就不适用了。 **File Uri 与 Content Uri 的区别** - File Uri 对应的是文件本身的存储路径 - Content Uri 对应的是文件在Content Provider的路径 所以在android 7.0 以上,我们就需要将File Uri转换为 Content Uri。
解决办法
1、在AndroidManifest.xml文件中添加如下代码<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_path" /> </provider>
注意:file_path名字为自定义,与下文的xml文件夹下的文件名字一样就可以
2、在res目录下新建文件夹xml,并新建一个文件,名称为上面自定义文件名
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>
3、开始调用相机
String path = Environment.getExternalStorageDirectory() + "/xxx/xx/"; File file = new File(path); if (!file.exists()) { file.mkdirs(); } String name = TimeUtil.getCurrentTimeLong() + ".png"; imgPath = path + name; File f = new File(path, name); Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { uri = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", f); } else { uri = Uri.fromFile(f); } Intent intentAlbum = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intentAlbum.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(intentAlbum, PHONE);
注意:当android版本高于4.4(SDK>=19,包含4.4)时使用7.0的规则,如果都使用7.0,可能会在一些低于4.4的手机会出现崩溃现象。
4、拍照完成后,在onActivityResult中做照片处理,在一些手机上,data可能为空,需要不同的处理。
Bitmap bitmap; if (null != data) { bitmap = data.getParcelableExtra("data"); } else { bitmap = BitmapFactory.decodeFile(imgPath); }
if (null != data) { startPhotoZoom(data.getData()); } else { String path = Environment.getExternalStorageDirectory() + "/"; String name = "head.png"; File f = new File(path, name); Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { uri = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", f); } else { uri = Uri.fromFile(f); } startPhotoZoom(uri); }
备注:处理成2中不同的对象,第一种为bitmap,直接操作图片,第二种为Uri,可以进行裁剪(文件路径必须以上面一样,忽略这个)
5、图片裁剪(系统方法)
Intent intent = new Intent("com.android.camera.action.CROP"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } intent.setDataAndType(uri, "image/*"); // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 300); intent.putExtra("outputY", 300); intent.putExtra("return-data", true); startActivityForResult(intent, TAILOR);
注意:3-5行处理裁剪在7.0失败的问题。
6、此文只是为了方便自己在下次忘后从新在度娘翻网页,只是为了方便。如果能帮助到你,更好!如果有什么错误,也可以留言,谢谢!
注意
想把拍照的照片保存到指定位置,但是在拍照完成后找不到该路径,处理照片时会出现空指针异常,要在开始拍照的时候先检查该路径下的文件夹是否存在,如果不存在,先创建。intentAlbum.putExtra(MediaStore.EXTRA_OUTPUT, uri);
相关文章推荐
- Android 7.0 之拍照与图片裁剪适配
- Android 7.0调用相机拍照,返回后显示拍照照片
- 一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库
- TakePhoto是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本3.0.0。
- android选择系统相机拍照和系统相册,裁剪图片并保存和设置头像,适配至7.0
- Android调用相册或相机拍照选取照片并裁剪
- Android从相册以及拍照选取照片,然后裁剪保存遇到的问题
- Android7.0 调用相机拍照并裁剪及遇到的坑
- Android 头像选择(拍照、相册裁剪),含7.0的坑
- Android拍照及图片裁剪、调用系统相册(兼容6.0以上权限处理及7.0以上文件管理)
- android拍照或相册选照片,裁剪,圆图处理(4.4变动后)
- Android调用相册或相机拍照选取照片并裁剪
- android 调用摄像头进行拍照,并对照片进行裁剪,然后显示。
- 如何兼容所有Android版本选择照片或拍照然后裁剪图片--基于FileProvider和动态权限的实现
- Android 中拍照、相册选择、裁剪照片
- mono for android 获取手机照片或拍照并裁剪保存
- Android 拍照并对照片进行裁剪和压缩实例详解
- Android 7.0 调用系统相机拍照、裁剪相片
- android7.0 拍照、相册选图、裁剪实现