Android7.0及以上下载后自动安装无法运行

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/One_Month/article/details/79657140

在最近的项目中,用到了下载新版然后自动安装更新的功能,但是发现在7.0手机上无法正常安装,查阅资料,发现在android 7.0的行为变更中有说明,文件共享发生了变化(自动安装就是系统的安装程序调用本项目的文件,等同于在跨应用访问数据)

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

要在应用间共享文件,您应发送一项 content:// URI,并授予 URI 临时访问权限。
进行此授权的最简单方式是使用 FileProvider 类。如需了解有关权限和共享文件的详细信息,请参阅共享文件。
                                                                            --摘自Android developer

这需要你在要共享的文件的项目中的AndroidManifest中进行配置


        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="建议是包名.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                 <!--这里配置一个xml文件,写明要共享的文件夹,也就是你要安装的apk的所在文件夹-->
                android:resource="@xml/provider_paths" />
        </provider>

上面的xml文件配置如下

<?xml version="1.0" encoding="utf-8"?>
<resource xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <!--
        我的文件放在内部缓存目录,所以用的cache-path 
        path  代表该路径下的子文件夹,如果apk不是直接在缓存目录,
        而是在缓存目录下一级的目录中就要写明,否则可以为空-->
        <!--
        external-path 为外部存储路径
        files-path 为内部存储路径
        name的值就像是一个常量,代表这path填写的路径,可以在请求数据Uri拼接使用,比如cotent://xxxx/download
        就等于content://xxxx/(path里的内容)
        -->
        <cache-path path="" name="download"/>
    </paths>
</resource>

注意:FileProvider来自于V4包,需要引入相关包
在自动安装的代码中就可以使用了

 File apkFile = new File(this.getCacheDir() + File.separator+apkName); //这是我的文件路径,各自根据自己的写
 if(Build.VERSION.SDK_INT>=24) {//判读版本是否在7.0以上
            Uri apkUri = FileProvider.getUriForFile(this, "com.example.holo.beikong.fileprovider"
            , apkFile);//在AndroidManifest中的android:authorities值
            Intent install = new Intent(Intent.ACTION_VIEW);
            install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            install.setDataAndType(apkUri, "application/vnd.android.package-archive");
            startActivity(install);
        } else{
            Intent install = new Intent(Intent.ACTION_VIEW);
            install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(install);
        }

fileprovider配置方式,Android developer开发者
希望能够给遇到同样麻烦的道友一些思路。

猜你喜欢

转载自blog.csdn.net/One_Month/article/details/79657140