zoukankan      html  css  js  c++  java
  • Android项目实战(四十):Andoird 7.0+ 安装APK适配

      

       首先看一下安装apk文件的代码

        /**
         * 通过隐式意图调用系统安装程序安装APK
         */
        public static void install(Context context) {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(
                    new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "xxxx.apk")),
                    "application/vnd.android.package-archive");
            context.startActivity(intent);
        }

      

        测试发现该段代码在7.0一下的机型上可以成功打开指定路径下的指定apk文件 , 但是在7.0+的机型上调用该代码会报错:

       android.os.FileUriExposedException: file:///storage/emulated/0/Download/xxxx.apk exposed beyond app through Intent.getData()

         原因在于:Android 7.0 版本开始  禁止向你的应用外公开 file:// URI。 如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常。

       

      解决方法:

      一、在AndroidManifest.xml 文件中添加 四大组件之一的 <provider>

        

     <!-- 适配7.0 apk安装 -->
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.xxx.xxxx.fileprovider" 
                android:grantUriPermissions="true"
                android:exported="false">
                <!--元数据-->
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>

       注意这里的  android :authorities 属性的值 中的 com.xxx.xxxx 是你的包名,不可随意填写

      二、res 目录下 建一个xml 文件,并新建xml文件file_paths.xml 

        注意文件名要和第一步中的 resource 属性的值一致 

        内容为:

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path path="." name="download"/>
    </paths>

      

      三、根据机型的Android系统级别执行不同的安装apk的代码

          注意,根据系统版本执行不同代码,7.0以下调用7.0+的代码会报错,7.0+的调用7.0以下的会报错。

          if (file!=null){   // file 即 apk文件
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    // 由于没有在Activity环境下启动Activity,设置下面的标签
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    if(Build.VERSION.SDK_INT>=24) { //判读版本是否在7.0以上
                        //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
                        Uri apkUri =
                                FileProvider.getUriForFile(context, "com.xxx.xxxxx.fileprovider", file);
                        //添加这一句表示对目标应用临时授权该Uri所代表的文件
                        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
                    }else{
                        intent.setDataAndType(Uri.fromFile(file),
                                "application/vnd.android.package-archive");
                    }
                    context.startActivity(intent);
                }
  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/xqxacm/p/8252188.html
Copyright © 2011-2022 走看看