android7.0以上安装apk

作者: sys_out | 来源:发表于2019-01-08 23:50 被阅读4次

    很多开发者应该都知道android7.0以上安装apk的问题。但是看了一些文章,并没有很好的帮助我解决问题。而且还有的坑没有被提到。

    android7.0安装apk会出现的问题和原因

    google在android7.0以上,禁止直接通过file://形式的uri向另一个应用传递文件uri。所以导致安装apk和相机拍照保存数据都会出现问题。google提供了FileProvider类来获取文件uri。FileProvider的本质也就是ContentProvider。

    简单回顾下ContentProvider

    ContentProvider做为android的四大组件之一,它主要的作用就是夸进程通信。从一个进程读取数据并提供给另一个进程。ContentProvider的底层是Binder机制(和AIDL一样)。
    ContentProvider核心由三个部分组成

    1. uri: 统一资源标识符 格式 content://com.aaa.bbb/user/1 。即:协议://授权(authority)/路径/id。表明了访问哪个进程(com.aaa.bbb)的哪个文件(user)。相关的类有URIMather(根据uri匹配)和ContentUri(在uri后面添加和获取id)。
    2. ContentResolver:用来帮助执行ContentProvider中的增删改查,简化操作。
    3. ContentOberser:监听某个uri下面数据变化,使用观察者模式。

    创建一个ContentProvider步骤就是 清单文件注册provider - 创建provider类,重写增删改查方法。访问ContentProvider步骤就是 创建uri contentProvider ContentResolver - 调用api访问。

    为啥要回顾呢?因为FileProvider就是ContentProvider。那么使用FileProvider好处是什么?当然是增加开发者工作量,减少花钱时间。。 。 好处大概是: 禁止过去的file://的方式向外部公开访问(我猜测是setUri(file://xxx)这个xxx文件就会被赋予外部应用的访问权限。不然为啥要换FileProvider),而通过FileProvider的方式给与临时权限。官方解释:

    对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file:// URI。如果一项包含文件 URI 的 intent 离开您的应用,则应用出现故障,并出现 FileUriExposedException 异常。

    要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
    https://developer.android.com/about/versions/nougat/android-7.0-changes.html#accessibility

    FileProvider如何使用

    这是固定步骤,不多赘述了。给个鸿洋的文章参考下:
    https://blog.csdn.net/lmj623565791/article/details/72859156
    但是我照着一模一样的做了,刚打开安装页面就闪掉。弄了大半天才发现问题。我使用的targetSdk为28,改成25就好了。为什么呢?原因是android8.0(ApiLevel26)以上需要添加权限,非正规来源apk的必须用户手动允许安装,才能进行下面的安装页面操作。

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    
    /** 
     * 判断是否是8.0系统,是的话需要获取此权限,判断开没开,没开的话处理未知应用来源权限问题,否则直接安装 
     */  
    private void checkIsAndroidO() {  
        if (Build.VERSION.SDK_INT >= 26) {  
            boolean b = getPackageManager().canRequestPackageInstalls();  
            if (b) {  
                publicApk();//安装应用的逻辑(写自己的就可以)  
            } else {  
                //请求安装未知应用来源的权限  
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_PACKAGES_REQUESTCODE);  
            }  
        } else {  
            installApk();  
        }  
    

    可以看看这篇文章
    https://blog.csdn.net/kac930/article/details/79131671

    到这里就结束了。这个权限的原因让我找了大半天才找到。之前把时间都耗在查看代码上,怎么都看不出来问题,同样的代码运行demo就没问题,在我的app就有问题(target 28)。所以下次遇到问题要换个思路、方向不能死脑筋了。

    相关文章

      网友评论

        本文标题:android7.0以上安装apk

        本文链接:https://www.haomeiwen.com/subject/lesirqtx.html