目录

那么如何处理这个权限呢?

1.应用的安装流程

2.首先申请权限

3.点击按钮进行应用安装

4.检查是否有未知应用来源的权限

5.执行安装流程

到这里就基本就完了,但有几个注意点:


前言:安卓系统升级到8.0之后,Google将未知应用安装权限的开关除掉了(原先打开这个开关所有的应用都会授予此权限),取而代之的是未知来源应用的管理列表,需要在里面打开每个应用的未知来源的安装权限。如果不处理这个未知来源的权限,那么将会阻塞内部应用启动安装过程,会导致应用根本无法更新,只能去应用市场重新下载。


那么如何处理这个权限呢?

1.应用的安装流程

1.先说说8.0之前的安装流程:

从服务器下载应用到本地 >>开启安装应用代码>>安装完成

2.  8.0之后应用安装流程:

从服务器下载应用到本地 >>代码打开安装位置来源应用界面>>授予权限>>开启安装应用代码>>安装完成

其中 “代码打开安装位置来源应用界面”会阻塞安装应用过程只有授予了安装未知应用的权限,才能继续执行安装过程。

3.为了模拟从网络上下载应用更新,我直接在内部存储放置了一个应用,点击安装,直接执行8.0的安装流程。

2.首先申请权限

    <!--读写内部存储权限--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><!--8.0安卓 软件安装需要申请的权限--><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

处理sdcard读取权限,代码如下:

 @TargetApi(Build.VERSION_CODES.M)private void checkSdCardPermission() {if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {installApk();} else {requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 100 & grantResults[0] == PackageManager.PERMISSION_GRANTED) {installApk();}}
重点是该权限:<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

3.点击按钮进行应用安装

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.btn_install).setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_install:checkInstallPermissionAndInstall();break;}}

代码很简单,一个执行安装的按钮

4.检查是否有未知应用来源的权限

 public void checkInstallPermissionAndInstall() {// 如果是8.0系统if (Build.VERSION.SDK_INT >= 26) {boolean b = getPackageManager().canRequestPackageInstalls();// 如果已经打开了安装未知来源的开关if (b) {checkSdCardPermission();} else {// 请求打开安装未知应用来源的界面,非运行时权限Uri packageURI = Uri.parse("package:" + getPackageName());Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);startActivityForResult(intent, GET_UNKNOWN_APP_SOURCES);}} else {checkSdCardPermission();}}

注释很清楚,这里只说重点:boolean b = getPackageManager().canRequestPackageInstalls();该行代码检查是否有未知应用来源的权限,如果有直接安装,没有就打开未知应用来源的界面。注意,这和运行时权限的申请是不同的!(很多人把运行时权限搞混了!)或者直接在清单文件中添加权限:

<!--安卓8.0打开apk安装更新--><uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

那么就不需要检查未知来源权限了,直接执行installApk方法

在onActivityResult()中处理回调结果,代码如下:

    @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case GET_UNKNOWN_APP_SOURCES:// 用户授予了未知来源应用的权限if (resultCode == RESULT_OK) {checkSdCardPermission();}break;default:break;}}

5.执行安装流程

执行安装代码:

private void installApk() {Uri uri = null;File file = new File(downLoadUrl);if (!file.exists()) {ToastUtil.showToast("文件不存在!");return;}// 安卓7.0及以上if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {uri = FileProvider.getUriForFile(this, getApplicationInfo().packageName + ".FileProvider", file);} else {uri = Uri.fromFile(file);}Intent intent = new Intent(Intent.ACTION_VIEW);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setDataAndType(uri, "application/vnd.android.package-archive");startActivity(intent);}

这里需要说的是,intent.setDataAndType(uri, "application/vnd.android.package-archive");中uri这个参数,同样需要对7.0及以上的系统进行适配,需要设置provider。

我是将应用直接放在了根目录下:

 private static final String downLoadUrl = Environment.getExternalStorageDirectory() + "/app-debug.apk";

provider配置如下:

        <!--安卓7.0及以上需配置provider --><providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.FileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths_public" /></provider>

file_paths_public.xml 文件内容如下:

<paths><!--指定共享的文件夹范围--><external-pathname="external_storage_root"path="." />
</paths>

path="." 表示内部存储的根目录

关于provider的配置,可以参见:https://blog.csdn.net/alex01550/article/details/82115074

中provider部分介绍,这里不再赘述。

到这里就基本就完了,但有几个注意点:

1.从内部存储安装应用需要sdcard运行时权限,如果没有该权限会提示解析错误!

2.启动安装界面时 intent.setDataAndType(uri, "application/vnd.android.package-archive"),中uri要记得做7.0适配!

3.在测试apk时,放在内部存储目录的apk,要通过build>>Build Apk(s) 进行构建,否则安装时会提示应用未安装!见下图

所以当你决定要适配到8.0的时候,一定要做其他方面的适配!

安卓8.0下的应用安装相关推荐

  1. linux7.0下mysql_CentOS 7.0下使用yum安装MySQL

    CentOS7默认数据库是mariadb,配置等用着不习惯,因此决定改成mysql,但是CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1 ...

  2. android 7.0 官方网址,Android7.0下载地址 安卓7.0系统手机下载安装教程

    导 读 安卓系统几乎是普及了所有人的手机,虽然6.0的安装率有点惨不忍睹,但是最近谷歌又有了新动作,在即将推出的安卓7.0系统又有哪些值得我们期待的功能呢?下面和小编一起去看看吧! 虽然Android ...

  3. android 7下载地址,Android7.0下载地址 安卓7.0系统手机下载安装教程

    安卓系统几乎是普及了所有人的手机,虽然6.0的安装率有点惨不忍睹,但是最近谷歌又有了新动作,在即将推出的安卓7.0系统又有哪些值得我们期待的功能呢?下面和小编一起去看看吧! 虽然Android 6.0 ...

  4. android 7.0下载地址,安卓7.0系统手机下载安装教程 Android7.0下载地址

    导 读 安卓系统几乎是普及了所有人的手机,虽然6.0的安装率有点惨不忍睹,但是最近谷歌又有了新动作,在即将推出的安卓7.0系统又有哪些值得我们期待的功能呢?下面和小编一起去看看吧! 虽然Android ...

  5. 安卓4.0 html5,原道N80测安卓4.0下HTML5和FLASH

    2012-3-23 11:16 [天极网数码频道]还记得安卓冰淇淋三明治系统刚刚推出时,由于其不支持FLASH,受到不少用户的指责.不过谷歌很快就补上了这一块短板,最新推出的安卓4.03系统,对在线视 ...

  6. android系统最新版本更新,安卓8.0系统最新下载安装

    安卓80系统升级是安卓手机最新升级更新系统,该系统拥有更多的功能特色,可以帮助用户朋友们更好的玩转安卓手机,赶紧下载,安卓手机并不比苹果差. 安卓80系统升级特色: 背景后台限制:谷歌从安卓7.0 N ...

  7. centos6.0下ffmpeg的安装编译经历

    最近因为要在linux上用ffmpeg处理一些视频,所以在学习centos下要安装ffmpeg,但是能搜到的安装教程感觉都不是很好用,至少我用起来感觉特别不爽,而且在ffmpeg的指令使用上格式写错了 ...

  8. air playit在安卓4.0下崩溃

    它的安卓版本是0.9.1,2012年1月发布后,一直没有更新. 安卓2.3的版本没有问题,4.0版本不正常. 表现在添加服务器: 填写完IP以后,点击加入服务器,会提示: air plyait已经停止 ...

  9. kail2.0下hping3的安装和使用

    第一部分,hping3的安装 0x01 首先是libpcap的安装 如果安装bison依赖包 运行如下命令 apt-get install bison 需要安装flex-2.6.0安装包,版本其他应该 ...

最新文章

  1. C# 中奇妙的函数–6. 五个序列聚合运算(Sum, Average, Min, Max,Aggregate)
  2. 鸿蒙2.0升级计划名单,鸿蒙OS 2.0适配 计划-升级名单
  3. 笔记:python3编写的仿hubot的聊天机器人Chattie
  4. 为什么网格布局不显示java_java – 在GridLayout中不显示组件的FlowLayout?
  5. python中的库有哪些餐厅_2017,最受欢迎的 15 大 Python 库有哪些?
  6. 贝塞尔曲线UIBezierPath简单使用
  7. Linux内存管理:Swap介绍以及如何使交换具有可扩展性
  8. 8.1 异常(Exceptions)
  9. CISSP考试要涨价了,5月1日起考试费涨为749美元
  10. 千锋锋云智慧联合百度重磅打造人工智能产业学院建设方案
  11. 科普:什么是CPU?CPU和芯片关系?CPU怎么做的?CPU有什么用?不同CPU有什么区别?我们怎么选CPU?(待补充完整)
  12. 微分几何 Class 2 欧氏空间
  13. LE-MSFE-DDNet:基于微光增强和多尺度特征提取的缺陷检测网络--论文笔记
  14. 你是不是程序员菜鸡,一句话就能证明!
  15. 腾讯Android自动化测试实战
  16. NR基础1-NR帧结构
  17. 51单片机实训(一)————基于Proteus的光控小夜灯
  18. 引用 oem 和主板bios修改方法
  19. 通过编程做特别效果的个性“微信”二维码(思路)
  20. java反射调用dubbo接口

热门文章

  1. 云学智慧校园-高校信息化一体化平台 V2.0 SE-WBS排期表(初拟)
  2. 麻省理工MIT计算机课程表
  3. Hadoop3.x学习教程(二)
  4. C++进阶笔记001:static 静态生存期 和 动态生存期
  5. 如何看待培训机构出来的非科班程序员
  6. 用c语言验证5阶魔方矩阵,穷举法打印n阶魔方矩阵
  7. python培训班课程大纲_Python课程大纲
  8. 时下最火的网络视频编码器传输技术
  9. Python爬虫——下载音乐
  10. 花呗部分用户已接入央行征信系统,快看你被选中了没?