解决 Android N 7.0 上 报错:android.os.FileUriExposedException
16lz
2021-01-23
//设置了超链接也不变色,还是直接写出来得了 Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/cn.bingoogolapple.update.demo/files/apk/BGAUpdateDemo_v1.0.0.apk exposed beyond app through Intent.getData()
看了下,估计是没有兼容android7.0的原因,这个作者的gradle设置的比较另类,我是第一次见,就没改,提交了issues,然后呢作者回复我让我改,估计他手头没有7.0的机器吧,我的也是前两天才升级了…
在这里把解决步骤记录一下..
1、在AndroidManifest.xml配置清单的Application中添加
<provider android:name="android.support.v4.content.FileProvider" android:authorities="app包名.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> provider>
注意: authorities:app的包名.fileProvider grantUriPermissions:必须是true,表示授予 URI 临时访问权限 exported:必须是false resource:中的@xml/file_paths是我们接下来要添加的文件
2、在res资源文件下新建目录xml,在xml目录下新建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path path="Android/data/app包名/" name="files_root" /> <external-path path="." name="external_storage_root" />paths>
path:需要临时授权访问的路径(.代表所有路径) name:就是你给这个访问路径起个名字
3、在Application中进行初始化判断
//解决 Android 7.0 后 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); }
4、然后就是对安装apk方法的更改:
/** * 跳转进行安装apk * @param file */ private void installApk(File file) { if (file != null) { Intent intent = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri contentUri = FileProvider.getUriForFile(context, "com.yoyoyt.learner.fileprovider", file); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } if (context.getPackageManager().queryIntentActivities(intent, 0).size() > 0) { context.startActivity(intent); } } }
1、首先我们对Android N及以上做判断; 2、然后添加flags,表明我们要被授予什么样的临时权限 3、以前我们直接 Uri.fromFile(apkFile)构建出一个Uri,现在我们使用FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", apkFile); 4、BuildConfig.APPLICATION_ID直接是应用的包名
如果包名写错了会空指针。。
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object referenceat android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:560)at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:534)at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:376)
更多相关文章
- android socket 配置文件
- Android学习笔记之mainfest文件中android属性
- android 下载文件注意事项
- mainfest文件中android属性
- ~/.dirlst 文件
- Android 读取和保存文件(手机内置存储器)
- Android——文件存储
- Android layout文件中 '?' 的作用
- :如何安装apk文件在Android仿真器中