Android7.0之前安装代码解析包出错的问题及解决办法

在Android7.0中引入了“私有目录访问受限”,使用FileProvider解决了问题,但是安装应用时解析包出错

让我们检查一下代码

    private void installApk(File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri apkUri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            apkUri = FileProvider.getUriForFile(mContext
                    , "项目包名.FileProvider"
                    , file);
        } else {
            apkUri = Uri.fromFile(file);
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        mContext.startActivity(intent);
    }

因为这个问题只出现在Android7.0,所以很容易认为可能是FileProvider引起的,但是查了半天,还是找不到是什么原因造成的。仔细对比7.0之前的安装代码,发现将intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)移到前面就可以正常安装了。

    private void installApk(File file) {
        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) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            apkUri = FileProvider.getUriForFile(mContext
                    , "项目包名.FileProvider"
                    , file);
        } else {
            apkUri = Uri.fromFile(file);
        }
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        mContext.startActivity(intent);
    }

具体原因

Android 7.0 通过 FileProvider 共享文件。因为exported为false,需要给目标应用授予临时权限,所以会设置intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

添加此权限后,intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 替换了添加的权限解析程序包出错,所以仍然没有授予权限。然后将intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)操作放在addFlags()之前或者替换成intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

图片[1]-Android7.0之前安装代码解析包出错的问题及解决办法-老王博客

这里要小心

setFlags():为 Intent 设置特殊标志,这将覆盖 Intent 已经设置的所有标志。

addFlags():为intent添加特殊标志,不会被覆盖,只会追加。

添加问题

在华为安卓8.0手机上,遇到上述方法无法解决的包解析错误。想起各种排查问题的方法解析程序包出错,分析猜测,锁屏时安装APK的服务可能处于休眠状态。不可用状态,导致intent.addFlags()临时授予的权限失效。

解决问题的改进代码如下

    private void installApk(File file) {
        try{
            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) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                apkUri = FileProvider.getUriForFile(mContext
                        , "项目包名.FileProvider"
                        , file);
            } else {
                apkUri = Uri.fromFile(file);
            }
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            // 查询所有符合 intent 跳转目标应用类型的应用,注意此方法必须放置在 setDataAndType 方法之后
            List resolveLists = mContext.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
            // 然后全部授权
            for (ResolveInfo resolveInfo : resolveLists){
                String packageName = resolveInfo.activityInfo.packageName;
                mContext.grantUriPermission(packageName, apkUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            }
            mContext.startActivity(intent);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论