Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决
项目更新遇到问题
Android项目开发中经常遇到下载更新的需求,以前调用系统安装器执行安装操作代码如下:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
context.startActivity(intent);
如果Android系统为7.0及以上时则会报异常FileUriExposedException,这是由于安卓官方为了提高私有文件的安全性,面向 Android 7.0 或更高版本的应用私有目录被限制访问 (0700)。此设置可防止私有文件的元数据泄漏,如它们的大小或存在性。传递file:// URI 可能给接收器留下无法访问的路径。因此,尝试传递 file:// URI 会触发 FileUriExposedException。因此需要使用 FileProvider。
Android7.0系统使用FileProvider安装apk安装步骤:
1.manifest.xml文件配置:定义一个FileProvider
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:theme="@style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="packageName.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
</application>
2.添加可用权限的文件目录
在项目res路径下新建名为xml的路径,在xml路径下新建名为file_paths.xml的文件,在file_paths.xml文件中增加如下内容指定分享的路径:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<external-path path="Android/data/packageName/" name="files_root" />
</PreferenceScreen>
3.使用provider直接安装apk:
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(contentUri, context.getContentResolver().getType(contentUri));
//指定打开文件所调用的Activity,若不指定,则会弹出打开方式选择框,
intent.setClassName("com.android.packageinstaller","com.android.packageinstaller.PackageInstallerActivity");
context.startActivity(intent);
完美适配所有系统版本进行apk安装的方式
如上代码虽然可以在Android7.0系统中正常安装apk,但是在低于Android7.0的系统中则不起作用,所以对apk安装调用方法进行封装,完美适配所有系统版本进行apk的安装调用。
/**
* 安装apk
*
* @param context Application对象
* @param path
* apk路径
*/
public static void InstallApk(Context context, String path) {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= 24) {//Android 7.0以上
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(contentUri, context.getContentResolver().getType(contentUri));
//指定打开文件所调用的Activity
intent.setClassName("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity");
} else {
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
}
context.startActivity(intent);
}
注意事项:
清单文件配置的authorities的值必须与FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", new File(path));方法中第二个参数一致。
Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决的更多相关文章
- 安装APK时报错:Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI]
安装APK时报错:Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI] 可以使用adb install -t 解决 对于已经在手机的文件可以使用pm ...
- Android studio 安装apk时报错:INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries
flutter项目 华为手机真机安装报错,解决 办法 app build.gradle android {...}内添加一下代码 splits { abi { enable true reset() ...
- Android安装apk时报错:INSTALL_FAILED_NO_MATCHING_ABIS
问题背景 OS:无关 AS:无关 Genymotion:2.5.2 Virtual Device:Google Nexus 5 - 5.1.0 - API 22 原因分析 CPU架构不符 解决方案 对 ...
- android命令安装apk时报错:INSTALL_FAILED_CPU_ABI_INCOMPATIBLE
点击下载Genymotion-ARM-Translation.zip 将你的虚拟器运行起来,将下载好的zip包用鼠标拖到虚拟机窗口中,出现确认对跨框点OK就行.然后重启你的虚拟机.
- 安装APK报错解决方法【转】
本文转载自:http://blog.csdn.net/zy1235678/article/details/38122827 adb install xxx.apk 报错,安装APK报错:INSTALL ...
- Android 在代码中安装 APK 文件
废话不说,上代码 private void install(String filePath) { Log.i(TAG, "开始执行安装: " + filePath); File a ...
- Android开发之深入理解Android 7.0系统权限更改相关文档
http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...
- 使用拷贝的方式(adb push) 绕过Android系统和adb install直接安装APK
某些情况下定制的Android系统为了限制用户安装应用,例如电视盒子,车载中控等,通过修改代码屏蔽了正常安装应用的方式 本文探讨如何在 adb shell 具有读写data分区目录的权限前提下,通过a ...
- Android 8.0系统的应用图标适配
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 参考资料<一起来学习Android 8.0系统的应用图标适配吧>中已经讲得很清楚了,这里我只是简单总结下.详情的内容请阅 ...
随机推荐
- 2016/1/20 笔记 1, 包 引入 static 已经补充到类里 2,继承
继承 1,关键字 extends 2,子类自动继承父类非私有的属性和方法 也叫成员变量 成员方法 3,super代表的是父类 调用父类的方法 默认在构造函数中生成 ...
- 修改ip 在linux上永久修改IP地址 子网掩码
小结: 1. 子网掩码.子网IP计算 2. linux centos 修改ip地址细节介绍_LINUX_操作系统_脚本之家 http://www.jb51.net/LINUXjishu/66509.h ...
- luogu1966 火柴排队
题目大意 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为: $\sum_{i=1}^n(a_i-b_i) ...
- YTU 2520: 小慧唱卡拉OK
2520: 小慧唱卡拉OK 时间限制: 1 Sec 内存限制: 128 MB 提交: 478 解决: 207 题目描述 小慧唱歌非常好听,小鑫很喜欢听小慧唱歌,小鑫最近又想听小慧唱歌了,于是小鑫请 ...
- C# oracle 参数传递的多种方式 留着复习
ORA-01036 非法的变量名/编号,(解决) 博客分类: oracle SQL 下边的代码就会造成 ORA-01036 非法的变量名/编号 cmd.CommandText = "SE ...
- 学习Flash Builder编程的准备工作
1. 下载教科书,Essential ActionScript 3.0或者Programming ActionScript 3.0.这将是你的很好的老师.英语不灵的买一本中文版本. 2. 安装Flas ...
- 【POJ 1679】 The Unique MST
[题目链接] 点击打开链接 [算法] 先求出图的最小生成树 枚举不在最小生成树上的边,若加入这条边,则形成了一个环,如果在环上且在最小生成树上的权值最大的边等于 这条边的权值,那么,显然最小生成树不唯 ...
- flask g对象
g对象 一次请求中使用 下面用redirect重定向,不是同一次请求了 g:global 1. g对象是专门用来保存用户的数据的. 2. g对象在一次请求中的所有的代码的地方,都是可以使用的. 使用 ...
- nginx - ubutun下安装nginx(详述编译方法)
一.使用apt命令安装 sudo apt-get install nginx 二.编译方法安装(个人实践方法,具体见官方文档) 1)说明:我使用的虚拟机是64位 ubuntu server14.04, ...
- poj 1201 Intervals【差分约束+spfa】
设s为前缀和,首先显然的条件是\[ s_{bi}-s_{ai-1}>=c \],然后隐含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然后根据差分约束, ...