Android 7.0 安装 App

前言

Andrid 7.0 继续提高了对用户隐私的保护和系统安全性,直接禁止掉了 file:// 协议,我们通常使用下面的代码安装apk就会出现问题:

    /**
     * 调用系统安装应用
     */
    public static boolean install(Context context, File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
        return true;
    }

在 7.0 的设备上运行的时候会报 FileUriExposedException (文件Uri暴露)错误:

Caused by: android.os.FileUriExposedException

解决办法是通过定义 FileProvider,观察发现使用的是content:// 协议

清单文件中定义 FileProvider


    

注意下 authorities字段,同一个手机上,只能有一个名字为这个 authoritiesProvider ,不能重复。

这里的 meta-data 设置了可访问的文件路径。

添加可访问的文件目录

在res目录下,增加xml文件夹,并新建一个名为 file_paths.xml 的文件。文件内容格式如下:


    

这里指定了根目录

与6.0及以下的系统兼容

以上这种通过 FileProvider 形式取得的 Uri 只能在 7.0 以上的设备上使用,在以下的系统回报这个错误:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.graypn.android_common.fileProvider/external_storage_root/szssmartparty.apk typ=application/vnd.android.package-archive flg=0x1 }

所以要有对不同的系统进行不同的处理,最终代码如下:

    /**
     * 调用系统安装应用
     */
    public static boolean install(Context context, File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri apkUri;
        // Android 7.0 以上不支持 file://协议 需要通过 FileProvider 访问 sd卡 下面的文件,所以 Uri 需要通过 FileProvider 构造,协议为 content://
        if (Build.VERSION.SDK_INT >= 24) {
            // content:// 协议
            apkUri = FileProvider.getUriForFile(context, "com.graypn.android_common.fileProvider", file);
            //Granting Temporary Permissions to a URI
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            // file:// 协议
            apkUri = Uri.fromFile(file);
        }
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        context.startActivity(intent);
        return true;
    }

你可能感兴趣的:(Android 7.0 安装 App)