赞
踩
Android 7.0之后对于文件访问安全性加强,一些旧的调用方法也发生了结果异常。
- public static boolean installApk(Context context, String apkPath) {
- File apkFile = new File(apkPath);
- if(!apkFile.exists() || !apkFile.isFile()) return false;
-
- Intent installIntent = new Intent(Intent.ACTION_VIEW);
- installIntent.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive");
- installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- context.startActivity(installIntent);
-
- // GNavigationBar.show(context); ///< show navigation bar
- // android.os.Process.killProcess(android.os.Process.myPid());
- return true;
- }
会出现如下异常:
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.xx.xxx/cache/imrider.apk exposed beyond app through Intent.getData()
使用自定义provider方式解决:
- public static void installMyApk(Context context, String path) {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- //判断是否是AndroidN以及更高的版本
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- Uri contentUri = FileProvider.getUriForFile(
- context,
- BuildConfig.APPLICATION_ID + ".fileProvider",
- new File(path));
- intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
- } else {
- intent.setDataAndType(
- Uri.fromFile(new File(path)),
- "application/vnd.android.package-archive");
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
- context.startActivity(intent);
- }
AndroidManifest.xml中的配置:
- <!--Android 7.0(api 24)以上使用file://访问文件需要用FileProvider方式-->
- <!--file_paths为配置的可访问路径-->
- <provider
- android:name="androidx.core.content.FileProvider"
- android:authorities="com.xx.xxx.fileProvider"
- android:grantUriPermissions="true"
- android:exported="false">
- <meta-data
- android:name="android.support.FILE_PROVIDER_PATHS"
- android:resource="@xml/file_paths" />
- </provider>
资源文件中新建file_paths.xml,用于存放可以访问的文件路径定义等:
- <?xml version="1.0" encoding="utf-8"?>
- <paths>
- <!-- <external-path path="Android/data/app的包名/" name="files_root" />-->
- <external-path path="." name="external_storage_root" />
- </paths>
android 8.0系统调用安装APK_xdy1120的博客-CSDN博客_android调用app安装 中说要配置一下权限:
- <!--安卓8.0打开apk安装更新-->
- <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
应该是配合他自己的代码使用的:
- private void openFile(final Context context) {
- //判读版本是否在8.0以上
- if (Build.VERSION.SDK_INT >= 26) {
- //来判断应用是否有权限安装apk
- boolean installAllowed= context.getPackageManager().canRequestPackageInstalls();
- if(installAllowed){
- installApk(context);
- }else {
- installApk(context);
- new Handler(Looper.getMainLooper()).post(new Runnable() {
- @Override
- public void run() {
- ToastUtil.ToastShort(context,"请设置开启允许安装未知应用");
- //此处只做提示,系统会自动弹框提醒,并可跳转开启
- // Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + context.getPackageName()));
- // context.startActivity(intent);
- }
- });
- }
- } else {
- installApk(context);
- }
- }
注:上述部分不写应该也是没有关系的。
Android碎片化严重,系统变更有时候会带来很多意外结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。