Android 7.0中拍照和图片裁剪适配的问题详解
发布时间 - 2026-01-10 22:55:38 点击率:次前言

Android 7.0系统发布后,拿到能升级的nexus 6P,就开始了7.0的适配。发现在Android 7.0以上,在相机拍照和图片裁剪上,可能会碰到以下一些错误:
Process: com.yuyh.imgsel, PID: 22995 // 错误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。
具体转换方法如下:
/**
* 转换 content:// uri
*
* @param imageFile
* @return
*/
public Uri getImageContentUri(File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.Media._ID },
MediaStore.Images.Media.DATA + "=? ",
new String[] { filePath }, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
那么,我们在裁剪的时候,应该如下调用:
private void crop(String imagePath) {
File file = new File("xxx.jpg");
cropImagePath = file.getAbsolutePath();
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(getImageContentUri(new File(imagePath)), "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", config.aspectX);
intent.putExtra("aspectY", config.aspectY);
intent.putExtra("outputX", config.outputX);
intent.putExtra("outputY", config.outputY);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, IMAGE_CROP_CODE);
}
这样就解决了裁剪的问题,但是!!拍照的时候就会出现以下错误:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
tempFile = new File(FileUtils.createRootPath(getActivity()) + "/" + System.currentTimeMillis() + ".jpg");
LogUtils.e(tempFile.getAbsolutePath());
FileUtils.createFile(tempFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
startActivityForResult(cameraIntent, REQUEST_CAMERA);
}
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg exposed beyond app through ClipData.Item.getUri()
这是因为拍照存储的文件,也需要以Content Uri的形式,故采用以下办法解决:
Step.1
修改AndroidManifest.xml
<application
...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="{替换为你的包名}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
Step.2
在res/xml/下新建provider_paths.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>
Step.3
修改拍照时的参数
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(getActivity(),BuildConfig.APPLICATION_ID + ".provider", tempFile)); //Uri.fromFile(tempFile)
总结
好了,以上就是这篇文章的全部内容了,希望本文的内容对各位Android开发者们能带来一定的帮助,如果有疑问大家可以留言交流。
# android
# 7.0适配拍照
# 7拍照适配
# 7.0
# 图片裁剪
# Android实现拍照、选择图片并裁剪图片功能
# Android裁剪图片为圆形图片的实现原理与代码
# 解决Android从相册中获取图片出错图片却无法裁剪问题的方法
# Android实现从本地图库/相机拍照后裁剪图片并设置头像
# Android实现拍照及图片裁剪(6.0以上权限处理及7.0以上文件管理)
# Android编程实现调用系统图库与裁剪图片功能
# android文件上传示例分享(android图片上传)
# Android使用post方式上传图片到服务器的方法
# Android实现本地上传图片并设置为圆形头像
# Android实现图片裁剪和上传
# 的是
# 用了
# 就会
# 好了
# 这篇文章
# 要以
# 这是因为
# 转换为
# 也需
# 方法如下
# 开始了
# 解决了
# 是由于
# 有疑问
# getAbsolutePath
# return
# public
# String
# getImageContentUri
# filePath
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在搬瓦工VPS快速搭建网站?
C++时间戳转换成日期时间的步骤和示例代码
Python数据仓库与ETL构建实战_Airflow调度流程详解
JavaScript中的标签模板是什么_它如何扩展字符串功能
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
专业商城网站制作公司有哪些,pi商城官网是哪个?
Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤
如何在阿里云ECS服务器部署织梦CMS网站?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
Laravel模型事件有哪些_Laravel Model Event生命周期详解
大连 网站制作,大连天途有线官网?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
动图在线制作网站有哪些,滑动动图图集怎么做?
如何快速查询网站的真实建站时间?
如何获取PHP WAP自助建站系统源码?
如何快速生成凡客建站的专业级图册?
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
Laravel PHP版本要求一览_Laravel各版本环境要求对照
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
如何在IIS中配置站点IP、端口及主机头?
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?
如何用JavaScript实现文本编辑器_光标和选区怎么处理
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
微信小程序 HTTPS报错整理常见问题及解决方案
javascript读取文本节点方法小结
Laravel如何使用Blade组件和插槽?(Component代码示例)
python中快速进行多个字符替换的方法小结
浅谈Javascript中的Label语句
UC浏览器如何设置启动页 UC浏览器启动页设置方法
bing浏览器学术搜索入口_bing学术文献检索地址
如何生成腾讯云建站专用兑换码?
Bootstrap整体框架之JavaScript插件架构
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
网站制作软件有哪些,制图软件有哪些?
音响网站制作视频教程,隆霸音响官方网站?
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
JS经典正则表达式笔试题汇总
javascript日期怎么处理_如何格式化输出
Laravel怎么连接多个数据库_Laravel多数据库连接配置
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
微信小程序 canvas开发实例及注意事项
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置

