Android 7.0/8.0 安裝APK時解析包錯誤問題

納尼小僧發表於2019-03-04

在android7.0上

 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);
    }

複製程式碼

這裡要注意 :

  • setFlags():為intent 設定特殊的標誌,會覆蓋 intent 已經設定的所有標誌。

  • addFlags():為intent 新增特殊的標誌,不會覆蓋,只會追加。

在Google8.0系統上在,遇到了上述方法無法解決的解析包出錯問題,後改進程式碼為如下,解決問題

 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<ResolveInfo> 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();
        }
    }

複製程式碼

相關文章