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() |
|
|
Context#getExternalFilesDir(String) Context.getExternalFilesDir(null) |
|
|
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"/>