在自定义应用程序中以编程方式安装 apk 时解析包时出错

error in parsing the package while installing apk programatically within the custom app

我正在构建一个应用程序,其中我使用下载管理器从 firebase 下载 apk,并希望在完成下载后在应用程序中自动安装 apk。

问题:完成下载 apk 后,安装过程无法运行,它会抛出错误“解析包时出错”,但手动运行(当我在后台点击下载通知时,安装过程有效但不在应用程序内)

我通过搜索同样的错误尝试了很多关于 Whosebug 的解决方案,但我没有弄清楚我在哪里做错了..

这是我的下载 apk 代码:

 private void Download() {

        //installtion permission

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (!getPackageManager().canRequestPackageInstalls()) {
                startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", getPackageName()))), 1234);
            } else {
            }
        }

        //Storage Permission

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
        }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }

        final ProgressDialog progressBarDialog= new ProgressDialog(this);
        progressBarDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressBarDialog.setTitle("Downloading...");
        progressBarDialog.setProgress(0);

        Uri uri=Uri.parse(Common.Url);
        DownloadManager.Request r = new DownloadManager.Request(uri);
        r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, Common.Apkname+".apk");
        r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        DownloadManager dm = (DownloadManager)getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
        final long downloadId =dm.enqueue(r);

           new Thread(new Runnable() {

            @Override
            public void run() {


                boolean downloading = true;


                while (downloading) {

                    DownloadManager.Query q = new DownloadManager.Query();
                    q.setFilterById(downloadId);

                    Cursor cursor = dm.query(q);
                    cursor.moveToFirst();
                    int bytes_downloaded = cursor.getInt(cursor
                            .getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                    int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));

                    if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
                        downloading = false;
                    }

                    final double dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);


                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {

                            progressBarDialog.setProgress((int) dl_progress);
                            progressBarDialog.setCanceledOnTouchOutside(false);

                        }
                    });
                    cursor.close();
                }

                progressBarDialog.dismiss();
                installAPK();
            }
        }).start();
        progressBarDialog.show();


    }

这是我的 installapk 代码:

void installAPK(){

        Context mContext = getApplicationContext();
        try {
            String PATH = Objects.requireNonNull(getApplicationContext().getExternalFilesDir(null)).getAbsolutePath();
            File file = new File(PATH + "/my_apk.apk");
            Intent intent = new Intent(Intent.ACTION_VIEW);
            if (Build.VERSION.SDK_INT >= 24) {
                Uri downloaded_apk = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", file);
                intent.setDataAndType(downloaded_apk, "application/vnd.android.package-archive");
                List<ResolveInfo> resInfoList = mContext.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolveInfo : resInfoList) {
                    mContext.grantUriPermission(mContext.getApplicationContext().getPackageName() + ".provider", downloaded_apk, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivity(intent);
            } else {
                intent.setAction(Intent.ACTION_VIEW);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
   }

希望这会起作用我刚刚将它从 kotlin 转换为 java

private final String APP_INSTALL_PATH = "\"application/vnd.android.package-archive\"";

    
public void installAPK(String destination, Uri uri, Context context) {
    
            BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
    
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
    
                        Uri fileProvider = FileProvider.getUriForFile(
                                context,
                                BuildConfig.APPLICATION_ID + ".provider",
                                new File(destination));
    
                        Intent install = new Intent(Intent.ACTION_VIEW);
                        install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
                        install.setData(fileProvider) ;
                        context.startActivity(install);
                        context.unregisterReceiver(this);
    
                    } else {
    
                        Intent install = new Intent(Intent.ACTION_VIEW);
                        install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        install.setDataAndType(
                                uri,
                                APP_INSTALL_PATH
                        );
                        context.startActivity(install);
                        context.unregisterReceiver(this);
    
    
                    }
    
    
                }
    
    
            };
    
            context.registerReceiver(broadcastReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    
    
    
        }