Android 7.0适配 APK文件下载及安装问题(利用FileProvider解决)

由于7.0上面添加了对文件访问的限制,所以需要额外兼容。Android 7.0强制启用了被称作 StrictMode的策略,带来的影响就是你的App对外无法暴露file://类型的URI了。
如果你使用Intent携带这样的URI去打开外部App(比如:打开系统相机拍照),那么会抛出FileUriExposedException异常。

manifest.xml中的application节点下面添加配置

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.betiger.fileprovider"
    android:grantUriPermissions="true" 
    android:exported="false"> 
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

res目录下新建xml目录,添加file_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
    name="download"
    path="Driver" />
</paths>
<!--代表外部存储区域的根目录下的文件 Environment.getExternalStorageDirectory()/DCIM/camerademo目录-->
<external-path name="hm_DCIM" path="DCIM/camerademo" />
<!--代表外部存储区域的根目录下的文件 Environment.getExternalStorageDirectory()/Pictures/camerademo目录-->
<external-path name="hm_Pictures" path="Pictures/camerademo" />
<!--代表app 私有的存储区域 Context.getFilesDir()目录下的images目录 /data/user/0/com.hm.camerademo/files/images-->
<files-path name="hm_private_files" path="images" />
<!--代表app 私有的存储区域 Context.getCacheDir()目录下的images目录 /data/user/0/com.hm.camerademo/cache/images-->
<cache-path name="hm_private_cache" path="images" />
<!--代表app 外部存储区域根目录下的文件 Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)目录下的Pictures目录-->
<!--/storage/emulated/0/Android/data/com.hm.camerademo/files/Pictures-->
<external-files-path name="hm_external_files" path="Pictures" />
<!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的images目录-->
<!--/storage/emulated/0/Android/data/com.hm.camerademo/cache/images-->
<external-cache-path name="hm_external_cache" path="" />

安装apk时调用

/**
 * 安装apk
 */
private void installSoft() {
    File file = new File(Config.PathConfig.downloadFile() ,"driver.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(mContext, "com.betiger.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");
    }
    mContext.startActivity(intent);
}

Android 8.0问题

当用户要从除了官方应用商店之外的来源安装App时(安装位置来源的APP):

Android8.0(Android-O)之前:可以被安装,或者需要打开系统设置当中“安装未知应用”权限,或者会有弹窗给用户一个提示。;Android8.0之后,Google进一步加强了权限管理,“安装未知应用”权限的永久开关被移除掉,每次当用户安装位置来源的App时,都需要单独授权并且对软件权限进行手动确认,这样的设计避免了被引诱安装带来的危害。当我们在Android8.0上安装位置来源Apk时,如果不进行设置或者代码控制,是不会跳转到系统App安装界面,就会导致App无法安装。

首先在AndroidManifest.xml清单文件中添加安装未知来源的权限

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

代码中在startActivity之前

//兼容8.0
if (android.os.Build.VERSION.SDK_INT >= 26) {
    boolean hasInstallPermission = getPackageManager().canRequestPackageInstalls();
    if (!hasInstallPermission) {
        //请求安装未知应用来源的权限
        ActivityCompat.requestPermissions((Activity) MainActivity.this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 6666);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容