最近刚刚把古老的项目targetSdk版本升级到26,升级之前是19(非常非常古老了)。那么升级后一些问题开始出现。

Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他无关应用。在应用权限设置的“特殊访问权限”中,加入了“安装其他应用”的设置,默认是关闭的。所以安装时需要授权用户去开启。

实现

1.清单文件权限声明

<uses-permissionandroid:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

  

2.点击安装判断是否有权限

    if (Build.VERSION.SDK_INT >= ) {
//来判断应用是否有权限安装apk
boolean installAllowed= getPackageManager().canRequestPackageInstalls();
//有权限
if (installAllowed) {
//安装apk
install(apkPath);
} else {
//无权限 申请权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_APK_REQUESTCODE);
}
} else {
install(apkPath);
}

权限申请回调

 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case INSTALL_APK_REQUESTCODE:
//有注册权限且用户允许安装
if (grantResults.length > && grantResults[] == PackageManager.PERMISSION_GRANTED) {
install(apkPath);
} else {
//将用户引导至安装未知应用界面。
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
startActivityForResult(intent, GET_UNKNOWN_APP_SOURCES);
}
break;
}
}

安装APK

    private void install(String apkPath) {
//7.0以上通过FileProvider
if (Environment.SYSTEM_VERSION_CODE >= ) {
Uri uri = FileProvider.getUriForFile(context, Environment.FILE_PROVIDER_AUTHORITY, new File(apkPath));
Intent intent = new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + apkPath), "application/vnd.android.package-archive");
context.startActivity(intent);
}
}

这里需要注意的是7.0引入了“私有目录被限制访问”,“StrictMode API 政策”。” StrictMode API 政策” 是指禁止向你的应用外公开 file:// URI。 如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常。

上面用到的代码中的Uri.fromFile 其实就是生成一个file://URL。一旦我们通过这种办法打开其它程序(这里打开系统包安装器)就认为file:// URI类型的 Intent 离开你的应用。这样程序就会发生异常。

解决办法:

FileProvider来解决这一问题,首先在清单文件中添加:

         <!-- FileProvider配置访问路径,适配7.0及其以上-->
<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/provider_paths" />
</provider>

authorities:app的包名;fileProvider grantUriPermissions:true;表示授予 URI 临时访问权限 exported:false ; resource:下一步添加的文件。

然后在res下新建一个名为xml的文件家,再新建文件provider_paths:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="files_root"
path="Android/data/com.example.downloadapk/"/>
<external-path
name="external_storage_root"
path="."/>
</paths>

path:需要临时授权访问的路径(.代表所有路径) name:给访问路径命名。

这样就可以完美解决7.0和8.0的问题啦!

BY LiYing

Android关于版本更新下载安装之踩坑记录(针对7.0以上)的更多相关文章

  1. CentOS7.4安装MySQL踩坑记录

    CentOS7.4安装MySQL踩坑记录 time: 2018.3.19 CentOS7.4安装MySQL时网上的文档虽然多但是不靠谱的也多, 可能因为版本与时间的问题, 所以记录下自己踩坑的过程, ...

  2. ubuntu 下安装docker 踩坑记录

    ubuntu 下安装docker 踩坑记录 # Setp : 移除旧版本Docker sudo apt-get remove docker docker-engine docker.io # Step ...

  3. 虚拟机安装mysql踩坑记录

    本章节主要讲解的是在虚拟机centOs7版本以上安装mysql5.6版本,亲测可以直接使用,有需要帮助的小伙伴可以加本人QQ2246451792@qq.com!!!! 卸载centOs7自带的mari ...

  4. windows 安装 python 踩坑记录

    官方不建议使用 64 bit python,容易出各种问题 Unable to find vcvarsall.bat 凡是安装与操作系统底层相关的 python 扩展都会遇到这个问题,如 PIL,Pi ...

  5. sqlserver安装和踩坑经历

    sqlserver安装和踩坑经历 下载 下载 安装 大致是按照这个来的 安装教程 出错 windows系统安装软件弹出"Windows installer service could not ...

  6. linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦(三)

    linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦(三) 安装PHP 1.yum方式安装PHP方法同安装apache一样传送门:linux cent ...

  7. linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦

    linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦(一) 一.Linux下安装MySQL 1.下载 下载地址:http://dev.mysql.co ...

  8. Xamarin.Forms教程Android SDK工具下载安装

    Xamarin.Form的Android SDK工具下载安装 本节将讲解如何下载Xamarin.Form的Android SDK工具,并使用其中的工具管理Android SDK,如何创建模拟器等内容. ...

  9. linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦(二)

    linux centos7环境下安装apache2.4+php5.6+mysql5.6 安装及踩坑集锦(二) 安装apache web容器 . yum方式安装apache 注意apache在linux ...

随机推荐

  1. P1616 疯狂的采药【模板】

    此题为NOIP2005普及组第三题的疯狂版. 此题为纪念LiYuxiang而生. 题目描述 LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师. ...

  2. SharedPreferences使用(通过键值保存数据)

    保存数据到SharedPreferences中 要想使用SharedPreferences来存储数据, 首先需要获取到SharedPreferences对象. Android中主要提供了三种方法用于得 ...

  3. Android stadio litepal

    今天看到技术交流群里有人招聘Android,要求会litepal. 我立马百度了下.嗯,我的学习技术的精神,是值得称赞的. litepal就是操作数据库的一个框架.git地址: https://git ...

  4. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  5. SSRS 报表管理器 http://localhost/Reports HTTP500 内部错误处理过程

    原文地址:http://www.cnblogs.com/zzry/p/5716056.html 安装了很多机器的sqlserverBI 组件 初始安装配置下 浏览报表管理器 http://localh ...

  6. jmter+ANT+jekins之配置文件简单优化(build.xml)

    <?xml version="1.0" encoding="utf-8"?> <project name="ant-jmeter-t ...

  7. [oldboy-django][2深入python] orm中auto_now =True, antu_now_add=True的应用

    DateTimeField.auto_now 这个参数的默认值为false,设置为true时,能够在保存该字段时,将其值设置为当前时间,并且每次修改model,都会自动更新.因此这个参数在需要存储“最 ...

  8. [oldboy-django][2深入django]ORM操作

    推荐学习博客:http://www.cnblogs.com/wupeiqi/articles/6216618.html 需求: 汇总django orm操作,代替原生mysql语句来操作数据库:里面内 ...

  9. java io 流 输入输出 大牛经典总结

    在软件开发中,数据流和数据库操作占据了一个很重要的位置,所以,熟悉操作数据流和数据库,对于每一个开发者来说都是很重要的,今天就来总结一下I/O,数据库操作 一:从数据流开始 首先先有一个结构图看一下整 ...

  10. java利用反射访问类的私有(private)属性及方法

    Java语言中,在一个类中,为了不让外界访问到有的属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的 ...