android 7.0 因为Uri.fromFile引起的FileUriExposedException异常

Android 7.0获取文件Uri适配 问题   在SDK升级到Android N,通过Uri.fromFile(file)获取Uri报 android.os.FileUriExposedException异常,因为在Android 7.0系统上,Android框架强制执行了StrictMode API政策禁止向应用外公开file:// URI,  如果Intent包含了file://类型的URI离开应用,抛出异常,退出程序。 阅读详情

最近作者又碰到因为android 7.0 引起的兼容问题了。

在7.0以前的版本:
//创建临时图片
File photoOutputFile = SDPath.getFile("temp.jpg", SDPath.PHOTO_FILE_STR);
Uri photoOutputUri = Uri.fromFile(photoOutputFile);

这个file文件直接非常简单的转换成"file://XXX/XXX/XXX"的uri格式

7.0后的版本:

当把targetSdkVersion指定成24及之上并且在API>=24的设备上运行时。这种方式则会出现FileUriExposedException异常

android.os.FileUriExposedException:         file:///XXX exposed beyond app through ClipData.Item.getUri()
    at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
    at android.net.Uri.checkFileUriExposed(Uri.java:2346)
    at android.content.ClipData.prepareToLeaveProcess(ClipData.java:832)
    at android.content.Intent.prepareToLeaveProcess(Intent.java:8909)
    ...
原因

Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。

原因在于使用file://Uri会有一些风险,比如:

  • 文件是私有的,接收file://Uri的app无法访问该文件。
  • 在Android6.0之后引入运行时权限,如果接收file://Uri的app没有申请READ_EXTERNAL_STORAGE权限,在读取文件时会引发崩溃。

因此,google提供了FileProvider,使用它可以生成content://Uri来替代file://Uri。

解决方案
首先声明: com.alex.demo 为项目的包名,以下需要包名的地方替换即可

第一步、

 在AndroidManifest.xml中加上摄像头、读写磁盘的权限,如下

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.CAMERA" />  
  2. <uses-permission android:name="android.permission.RECORD_AUDIO" />  
  3. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
  4. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  

第二步、

 在AndroidManifest.xml中加上自定义权限的ContentProvider,如下

[html]  view plain  copy
  1. <provider  
  2.             android:name="android.support.v4.content.FileProvider"  
  3.             android:authorities="com.alex.demo.FileProvider"  
  4.             android:exported="false"  
  5.             android:grantUriPermissions="true">  
  6.             <meta-data  
  7.                 android:name="android.support.FILE_PROVIDER_PATHS"  
  8.                 android:resource="@xml/file_paths" />  
  9.         </provider>  

[html]  view plain  copy
  1. android:authorities="com.alex.demo.FileProvider" 自定义的权限  
[html]  view plain  copy
  1. android:exported="false" 是否设置为独立进程  
[html]  view plain  copy
  1. android:grantUriPermissions="true" 是否拥有共享文件的临时权限  
[html]  view plain  copy
  1. android:resource="@xml/external_storage_root" 共享文件的文件根目录,名字可以自定义  

第三步、

在项目res目录下创建一个xml文件夹,里面创建一个file_paths.xml文件,上一步定义的什么名称,这里就什么名称,如图:


[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <paths>  
  3.     <external-path  
  4.         name="external_storage_root"  
  5.         path="." />  
  6. </paths>  

[html]  view plain  copy
  1. name="external_storage_root" 这个是根目录名称,可以自定义  

好了,基本工作准备好,下面开始具体的使用吧


1、调用系统相机

[html]  view plain  copy
  1. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
  2.             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  3.             String filePath = ShowConfig.getCacheFolderPath() + File.separator + ".temp.jpg";  
  4.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  5.                 mOriginUri = FileProvider.getUriForFile(BaseApplication.getApplication(), BaseApplication.getApplication().getPackageName() + ".FileProvider",  
  6.                         new File(filePath));  
  7.             } else {  
  8.                 mOriginUri = Uri.fromFile(new File(filePath));  
  9.             }  
  10.             intent.putExtra(MediaStore.EXTRA_OUTPUT, mOriginUri);  
  11.   
  12.             if(mAttachedFragment == null)  
  13.                 mAttachedActivity.startActivityForResult(intent, REQUEST_CROP_CAM_IMG_CODE);  
  14.             else  
  15.                 mAttachedFragment.startActivityForResult(intent, REQUEST_CROP_CAM_IMG_CODE);  
2、调用系统播放器播放视频

[html]  view plain  copy
  1. Intent intent = new Intent();  
  2.             intent.setAction(android.content.Intent.ACTION_VIEW);  
  3.             File file = FileUtils.createFile(mSelectedVideoPath);  
  4.             Uri uri;  
  5.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  6.                 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  7.                 Uri contentUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".FileProvider", file);  
  8.                 intent.setDataAndType(contentUri, "video/*");  
  9.             } else {  
  10.                 uri = Uri.fromFile(file);  
  11.                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  12.                 intent.setDataAndType(uri, "video/*");  
  13.             }  
  14.   
  15.             startActivity(intent);  
3、切图
[html]  view plain  copy
  1. Intent intent = new Intent("com.android.camera.action.CROP");  
  2.                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  3.                 intent.setDataAndType(uri, "image/*");  
  4.                 Uri customUri = null;  
  5.                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  6.                     customUri = FileProvider.getUriForFile(BaseApplication.getApplication(), BaseApplication.getApplication().getPackageName() + ".FileProvider",  
  7.                             new File(mLocalAvatarImagePath));  
  8.                 } else {  
  9.                     customUri = Uri.fromFile(new File(mLocalAvatarImagePath));  
  10.                 }  
  11.                 intent.putExtra("output", customUri);  
  12.                 intent.putExtra("crop", "true");  
  13.                 intent.putExtra("aspectX", 1);  // 裁剪框比例  
  14.                 intent.putExtra("aspectY", 0.75);  
  15. //            intent.putExtra("outputX", mOutputWidth);  // 输出图片大小  
  16. //            intent.putExtra("outputY", mOutputHeight);  
  17.                 intent.putExtra("scale", true);  // 去黑边  
  18.                 intent.putExtra("scaleUpIfNeeded", true);  // 去黑边  
  19.                 if(mAttachedFragment == null)  
  20.                     mAttachedActivity.startActivityForResult(intent, REQUEST_UPLOAD_IMG_CODE);  
  21.                 else  
  22.                     mAttachedFragment.startActivityForResult(intent, REQUEST_UPLOAD_IMG_CODE);  

4、用系统安装器安装APK

[html]  view plain  copy
  1. Uri fileUri = null;  
  2.                             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  3.                                 fileUri = FileProvider.getUriForFile(BaseApplication.getApplication(), BaseApplication.getApplication().getPackageName() + ".FileProvider",  
  4.                                         new File(filePath));  
  5.                             } else {  
  6.                                 fileUri = Uri.fromFile(new File(filePath));  
  7.                             }  
  8.                             Intent installIntent = new Intent(Intent.ACTION_VIEW);  
  9.                             installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  10.                             installIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  11.                             installIntent.setAction(Intent.ACTION_VIEW);  
  12.                             installIntent.setDataAndType(fileUri,  
  13.                                     "application/vnd.android.package-archive");  
  14.                             context.startActivity(installIntent);  
我所碰到的异常
1、java.lang.SecurityException: Provider must not be exported
解决方案:android:exported必须设置成false
2、Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
解决方案:AndroidManifest.xml处的android:authorities必须跟mActivity.getPackageName() + ".fileprovider"一样

此文章是我在使用过程中遇到问题时所搜到的,并且把两篇文章的重要部分综合了一下,方便遇到同样的问题能快速的处理。如果大家在使用的过程中还有遇到其他的 问题以及解决办法,欢迎留言。我把这两篇文章的原稿地址留在下面;

http://blog.youkuaiyun.com/msn465780/article/details/59058088?locationNum=8&fps=1;

http://www.jianshu.com/p/55b817530fa3;


Android 8.0 调取系统摄像头和相册选择图片 最近做了几个商城,发现个人中心那,头像修改都是统一一种模式,调取系统摄像头和相册上传头像.就写个总结,以后就直接拿来用,顺便总结遇到的问题. 6.0之后敏感权限动态申请 7.0之后 使用本地真实的Uri路径不安全,直接使用Uri.fromFile(file);会报FileUriExposedException异常 android.os.FileUriExposedException: file... 阅读详情

相关推荐

Playwright自动化测试实战:攻克日历时间控件三大策略与Java实现

在Web自动化测试领域,元素定位与交互模拟是核心技术基础,其原理在于通过程序精确识别并操作页面中的DOM元素,以模拟真实用户行为。这项技术的核心价值在于提升测试效率、确保交互逻辑的覆盖度与可靠性,广泛应用于电商、金融、OA等系统的功能验证。日历时间控件作为典型的复杂交互组件,常涉及动态弹出层、多级导航与状态同步,是自动化测试中的常见难点。本文聚焦于使用Playwright工具,针对此类控件深入剖析了三种核心解决策略:从最高效的直接赋值、到全面模拟用户交互的主流方法,再到利用组件特性的混合定位方案,并结合Ja

weixin_28835551的博客 311

看我如何解决“包解析错误”问题

//getExternalCacheDirs() 既然了解了,我指定的也是没有毛病啊,但是还是不行,我重新看了下报错信息,发现报错信息中有 that is not exported 是不是在provider中exported的参数设置问题,感觉找到了希望,我急忙去改这个参数,运行程序,噢噢,直接崩溃了。这是什么鬼。看下日志: java.lang.SecurityException: Provider must not be exported 大概的意思就是不能设置为exported为true,看来问题还.

m0_70083119的博客 1890

香橙派OPi 6系列选型指南:RK3588与RK3588S开发板深度对比

开发板选型是嵌入式系统设计的关键环节,尤其在边缘计算和AI推理等场景中,芯片的差异直接影响硬件架构。瑞芯微RK3588及其精简版RK3588S是当前高端开发板的核心方案,两者在PCIe通道、显示输出和SATA支持上存在显著区别。理解这些原理,有助于工程师根据项目需求快速匹配产品。香橙派OPi 6系列基于这两款芯片,衍生出OPi 6、OPi 6 Pro与OPi 6 Max三种形态:紧凑型适合嵌入式门禁与AI盒子,Pro版凭借双屏异显和PCIe 3.0满足收银机与视频分析,Max的双2.5G网口和大内存则面向轻

weixin_29185167的博客 224

Android:java.lang.SecurityException: Provider must not be exporte

是用来标识provider的唯一标识,在同一部手机上一个"authority"串只能被一个app使用,冲突的话会导致app无法安装。android:grantUriPermissions用来控制共享文件的访问权限,也可以在java代码中设置。android:exported必须设置成false,后面异常会讲为什么。首先在AndroidManifest.xml中添加provider。

weixin_52173254的博客 803

雪球股票数据接口

周期(day-日,week-周,…表示获取前8个周期(日)数据):类型(before-历史)表示深圳证券交易所,表示上海证券交易所):开始时间戳(一定要。

qq_31856061的博客 6807

【HSPiP应用指南】从理论到实践:如何利用汉森溶解度参数优化配方设计

本文深入解析了汉森溶解度参数(HSP)理论及其在配方设计中的核心价值,并详细介绍了如何利用HSPiP软件工具从理论走向实践。文章通过匹配溶解度参数、计算汉森距离(Ra),系统阐述了如何解决溶剂选择、颜料分散稳定性及扩散行为预测等关键问题,并结合界面气相色谱(IGC)等实验方法提升预测精度,旨在帮助配方师实现配方设计的可视化、可量化与高效优化。

weixin_29305313的博客 1646

Android 异常:Caused by: java.lang.SecurityException: Provider must not be exported

android 异常

宇宙精英 2021

Ollama-OCR实战:5分钟搞定PDF文档转Markdown(附qwen2.5vl模型配置)

本文详细介绍了如何利用Ollama本地部署多模态大模型qwen2.5vl,结合OCR技术,实现PDF文档到Markdown的端到端智能转换。通过解析传统OCR的局限与AI方案的优势,并提供从环境搭建、提示词工程到处理复杂表格的完整实战指南,帮助用户高效构建自动化文档处理流水线,彻底重塑文档处理工作流。

yog99的博客 604

Android7.0 以上版本 使用 Uri.fromFile(File) 报错

我在学习Android中Camera的时候发现,如果我们想要原图,直接读取图片位置显示的时候程序直接崩溃了,我发现报了下面这个错误: android.os.FileUriExposedException: file:///storage/emulated/0/temp.png exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)..

qq_19688207的博客 3612

微信小程序使用TCP通信

最终目的:在微信小程序内实现对局域网发起TCP通信实现步骤:建立TCP服务 + 小程序发起通信。

Big_YiFeng的博客 5612

海康工业相机LabVIEW二次开发实战——参数配置优化与图像高效存储

本文详细介绍了海康工业相机在LabVIEW平台上的二次开发实战,重点解析了相机参数配置的优化方法与图像高效存储策略。通过剖析曝光、增益、触发模式等核心参数的设置逻辑,并结合生产者-消费者设计模式,指导开发者构建稳定、高效的图像采集与异步存储流程,有效提升工业视觉项目的开发效率与系统稳定性。

weixin_29306317的博客 221

Android7.0、8.0应用内安装apk的问题

文章转载于http://www.aoaoyi.com/archives/840.html,部分个人修改的地方以红色文字显示。Android开发避免不了应用内发起安装应用,随着Android版本的升级,权限越来越收紧,安装姿势变了又变。接下来我来告诉大家针对不同Android版本正确发起应用内安装。首先将现有的Android版本进行分一下界限,Android 1.x~6.x 和Android 7.x...

qq_24973893的博客 1万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

android7.0 获取uri

android7.0 获取uriandroid7.0以后,使用Uri.fromFile会报FileUriExposedException异常,这是因为android7.0以后执行了更加严格的文件管理,要解决这一错误需要使用7.0新添加的FileProvide类,FileProvider官方文档:官方链接FileProvider使用步骤:1、定义一个FileProvider在manifest里面定义一

see876的博客 4166

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

android7.0 通过FileProvider获取uri

android7.0以后,使用Uri.fromFile会报FileUriExposedException异常,这是因为android7.0以后执行了更加严格的文件管理,要解决这一错误需要使用7.0新添加的FileProvide类, FileProvider使用步骤: 1、注册一个FileProvider 在manifest里面定义一个FileProvider: <manifest> ...

muranfei的博客 2338

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

94.android7.0 获取uri

链接:https://blog.csdn.net/lanxuan1993/article/details/81627436 借鉴:https://blog.csdn.net/qq_33505109/article/details/90405302 android7.0以后,使用Uri.fromFile会报FileUriExposedException异常,这是因为android7.0以后执行了...

lanxuan1993的博客 301

Android7.0文件共享问题(FileUriExposedException)

在安卓7.0以上机型,在使用Uri uri=Uri.fromFile();会报android.os.FileUriExposedException: file:///storage/emulated/xxx异常,比如拍照时,常用的写法是:Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

白玉梁的专栏 3486

Android 7.0自动安装apk

在7.0之前安装的时候,只需要通过隐式Intent来跳转,并且指定安装的文件Uri即可,代码如下: Intent intent = new Intent(Intent.ACTION_VIEW); //由于没有在Activity环境下启动Activity,设置下面的标签 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDat...

qq_34022794的博客 975

android 7.0项目电子书,android文件分享在android7.0以上版本报错的解决方案

最近在使用蓝牙进行文件分享时,出现了一个奇怪的问题。同样的代码在android5.1上可以顺利运行,但是在android7.0上就运行失败。出现如下的错误:Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/bluetooth/data.txt exposed beyond app through Cl...

weixin_39972768的博客 5289

android7.0uri,android7.0 通过FileProvider获取uri

android7.0以后,使用Uri.fromFile会报FileUriExposedException异常,这是因为android7.0以后执行了更加严格的文件管理,要解决这一错误需要使用7.0新添加的FileProvide类,FileProvider使用步骤:1、注册一个FileProvider在manifest里面定义一个FileProvider:............name直接使用系统...

weixin_29442195的博客 2176

FileUriExposedException产生的原因

1.情况描述 targetVersion 7.0及以上的手机,Uri.fromFile()方法使用时,并通过startActivity等方式启动其他app时,会出现FileUriExposedException异常。 2.问题原因及解决方案 为了提高私有文件的安全性,Android框架执行StrictMode API政策,禁止在应用内公开file:// URL,如果一项包含文件URI的int...

jojoliya的专栏 1492

Android出现android.os.FileUriExposedException: exposed beyond app through Intent.getData()问题

错误提示:android.os.FileUriExposedException: exposed beyond app through Intent.getData() 出现场景:在实现拼图游戏App中选择拍照后图片作为拼图背景时,App闪退报错。 出现原因:从Android7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,会抛出FileUriExposedException异常。...

qq_41853047的博客 1983

Android用外部应用打开文件,Android N 以上使用其他应用打开文件 FileProvider

又是好长一段时间没有写东西了,说忙到没有时间写东西,这个说法在任何时候都是借口。总的来说还是没有写,真的要写的话还是有时间来写的,不说成为一个高产的人吧,但是稍微写一些的时间还是有的,再不济也可以分开到很多天再来写的吧。所以说这到头来还是个人的问题,没有主动有意识的去写这些东西,没有有意识的去学习去分享。这也在一定程度上说自己这段时间主动学习的时间少了。无论如何,还是要好好学习的,虽然已经不再学校...

weixin_30843553的博客 1113

Android_7.0 因为file://引起的FileUriExposedException异常

最近接手公司的apk更新迭代时发现每次下载完新版本跳转安装时apk就闪退查看log发现问题FileUriExposedException,原因是Android不再允许在app中把file://Uri暴露给其他app,包括但不局限于通过Intent或ClipData 等方法。因此提出一下解决方案:步骤一:在清单文件applicantion中添加如下代码: &lt;provider ...

码农曾的博客 558
上一篇: WebView 的新增安全功能
下一篇: Fragment里面的Viewpaper不显示内容不执行getItem的解决方案
android_an
博客等级 码龄11年 1粉丝 3原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值