Android 6.0 / 7.0 / 8.0 的APK安装

Android 1.x~6.x APK安装

关于 android 7.0 之前的 apk安装,需要注意设置 Intent.FLAG_ACTIVITY_NEW_TASK 就好

    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri apkUri = Uri.fromFile(file);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    startActivity(intent);

Android 7.x APK安装

在 Android 7.0 引入了“私有目录被限制访问”,“StrictMode API 政策”。 Android 7.0 行为变更

” StrictMode API 政策” 是指禁止向你的应用外公开 file:// URI。使用上述方法安装APK时会出现 FileUriExposedException 异常。这个时候就需要使用FileProvider来解决这个问题:

---------------------------------------------------------------------------------------------------------------------

步骤一 (FileProvider的申请),在Manifest.xml中定义一个FileProvider,代码如下:

<application>

    <provider
        android:name="android.support.v4.content.FileProvider" // 指向v4包里的FileProvider类
        android:authorities="你的包名.FileProvider" // 对应你的content uri的基础域名,生成的uri将以content://你的包名.FileProvider作为开头
        android:exported="false" // 设置不允许导出,我们的FileProvider应该是私有的
        android:grantUriPermissions="true"> // 设置允许获取访问文件的临时权限
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/apk_provider_paths" /> // 用于设置FileProvider的文件访问路径
    </provider>

</application>

 注意 android:authorities="你的包名.FileProvider" 中 “你的包名”为你当前项目包名

---------------------------------------------------------------------------------------------------------------------

步骤二 (创建 .xml),在res目录新建xml文件夹,如图所示

xml文件下的 .xml文件名与步骤一中 android:resource="@xml/apk_provider_paths"  引用的名称一致

---------------------------------------------------------------------------------------------------------------------

步骤三 (配置FileProvider文件共享的路径),在 apk_provider_paths.xml文件中配置:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="应用名称"
        path="apk所在路径" />
</paths>

在标签中我们必须配置至少一个或多个path子元素, path子元素则用来定义content uri所对应的路径目录。 

这里说明一下, 例如将 APK 下载到了  Environment.getExternalStorageDirectory() + "/aaa/bbb" 目录下,则配置如下

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="xxx"
        path="/aaa/bbb" />
</paths>

如果你的 APK不是在 sdcard目录下,那么 apk_provider_paths.xml中的 paths 需要进行重新配置。具体可参考点击查看或者Android7.0

根据文档提示,我们使用FileProvider进行处理,同时利用xml对FileProvider进行配置 ,可参考如下

Java根路径产生方式 对应xml根节点名称
Context.getFilesDir() files-path
getCacheDir() cache-path
Environment.getExternalStorageDirectory()

external-path

Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)
external-files-path
Context.getExternalCacheDir() external-cache-path

具体升级代码

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Uri apkUri;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        // 授予文件操作的临时权限,根据需求设定,一般安装只需要READ权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);    
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // 获取配置的FileProvider的 Content Uri的值
        apkUri = FileProvider.getUriForFile(mContext
            , "你的包名.FileProvider"
            , file);
    } else {
        apkUri = Uri.fromFile(file);
    }
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    startActivity(intent);

Android 8.x APK安装

在Android 8.0 Oreo 中,Google 移除掉了容易被滥用的“允许位置来源”应用的开关,在安装 GooglePlay Store 之外的第三方来源的 Android 应用的时候,竟然没有了“允许未知来源”的检查框,如果你还是想要安装某个被自己所信任的开发者的 app,则需要授予“安装未知应用”的许可。

静态权限设置:

在Manifest.xml配置文件中添加以下权限,这个不是危险权限,可以不用动态申请。

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

猜你喜欢

转载自blog.csdn.net/lmy820200104/article/details/84105200