最近刚刚把古老的项目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. 适合学习的QT开源项目-SerialTool

    https://github.com/Skiars/SerialTool A cross platform Serial-Port/TCP/UDP debugging tool. SerialTool ...

  2. String使用方法详解

    标准c++中string类函数介绍 注意不是CString 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够.字符串长度等等,而且作 ...

  3. sql优化系列2

    sql中索引是否会用到,进而影响查询效率. 带通配符(%)的like语句 1.不能用null作索引,任何包含null值的列都将不会被包含在索引中.即使索引有多列这样的情况下,只要这些列中有一列含有nu ...

  4. HDU 3032 Nim or not Nim?(Multi_SG,打表找规律)

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  5. Python虚拟机类机制之绑定方法和非绑定方法(七)

    Bound Method和Unbound Method 在Python中,当对作为属性的函数进行引用时,会有两种形式,一种称为Bound Method,这种形式是通过类的实例对象进行属性引用,而另一种 ...

  6. hive操作语句

    设置属性: //设置本地执行作set hive.exec.mode.local.auto=true; //设置动态分区 set hive.exec.dynamic.partition=true; se ...

  7. Eclipse安装MAT插件

    MAT(Memory Analyzer Tool) 是基于heap dumps来进行分析的,它的分析速度比jhat快,分析结果是图形界面显示,比java内置jhat的可读性更高 通过Eclipse市场 ...

  8. Python-S9—Day85-ORM项目实战之forms组件以及Modelform补充、跨域请求及应用

    01 forms组件补充1 02 forms组件补充2 03 ModelForm回顾 04 浏览器的历史 05 jsonop实现跨域请求 06 jsonop实现跨域请求2 07 jsonop实现跨域请 ...

  9. CSU-2221 假装是区间众数(ST表模版题)

    题目链接 题目 Description 给定一个非递减数列Ai,你只需要支持一个操作:求一段区间内出现最多的数字的出现次数. Input 第一行两个整数N,Q 接下来一行有N个整数,表示这个序列. 接 ...

  10. Unity 碰撞检测

    武器与怪物的碰撞 目前来说有三种思路,其实前两种算变种了: 1.动画关键帧回调 + 范围检测.http://blog.csdn.net/u013700908/article/details/52888 ...