2

Background: I am installing android app programmatically using PackageInstaller.

What am I doing: The code which I am using is mentioned below. This is the same code which has been provided in PackageInstaller sample by google.

        private void init() {
        PackageInstaller.Session session = null;
                try {
                    PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
                    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                            PackageInstaller.SessionParams.MODE_FULL_INSTALL);
                    int sessionId = packageInstaller.createSession(params);
                    session = packageInstaller.openSession(sessionId);
                    addApkToInstallSession("HelloActivity.apk", session);
                    // Create an install status receiver.
                    Context context = InstallApkSessionApi.this;
                    Intent intent = new Intent(context, InstallApkSessionApi.class);
                    intent.setAction(PACKAGE_INSTALLED_ACTION);
                    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
                    IntentSender statusReceiver = pendingIntent.getIntentSender();
                    // Commit the session (this will start the installation workflow).
                    session.commit(statusReceiver);
                } catch (IOException e) {
                    throw new RuntimeException("Couldn't install package", e);
                } catch (RuntimeException e) {
                    if (session != null) {
                        session.abandon();
                    }
                    throw e;
                }
            }
        });
    }

        private void addApkToInstallSession(String assetName, PackageInstaller.Session session)
            throws IOException {
        // It's recommended to pass the file size to openWrite(). Otherwise installation may fail
        // if the disk is almost full.
        try (OutputStream packageInSession = session.openWrite("package", 0, -1);
             InputStream is = getAssets().open(assetName)) {
            byte[] buffer = new byte[16384];
            int n;
            while ((n = is.read(buffer)) >= 0) {
                packageInSession.write(buffer, 0, n);
            }
        }
    }
    // Note: this Activity must run in singleTop launchMode for it to be able to receive the intent
    // in onNewIntent().
    @Override
    protected void onNewIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        if (PACKAGE_INSTALLED_ACTION.equals(intent.getAction())) {
            int status = extras.getInt(PackageInstaller.EXTRA_STATUS);
            String message = extras.getString(PackageInstaller.EXTRA_STATUS_MESSAGE);
            switch (status) {
                case PackageInstaller.STATUS_PENDING_USER_ACTION:
                    // This test app isn't privileged, so the user has to confirm the install.
                    Intent confirmIntent = (Intent) extras.get(Intent.EXTRA_INTENT);
                    startActivity(confirmIntent);
                    break;
                case PackageInstaller.STATUS_SUCCESS:
                    Toast.makeText(this, "Install succeeded!", Toast.LENGTH_SHORT).show();
                    break;
                case PackageInstaller.STATUS_FAILURE:
                case PackageInstaller.STATUS_FAILURE_ABORTED:
                case PackageInstaller.STATUS_FAILURE_BLOCKED:
                case PackageInstaller.STATUS_FAILURE_CONFLICT:
                case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
                case PackageInstaller.STATUS_FAILURE_INVALID:
                case PackageInstaller.STATUS_FAILURE_STORAGE:
                    Toast.makeText(this, "Install failed! " + status + ", " + message,
                            Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(this, "Unrecognized status received from installer: " + status,
                            Toast.LENGTH_SHORT).show();
            }
        }
    }

User Consent Dialog

Query: The code works perfectly fine but PackageInstaller doesn't give any status on clicking the INSTALL button where as onclicking the CANCEL button, it provides status. I have to perform some action when user confirms installation by clicking install button. Is there any other way to get the status when install button is clicked?

Note: I don't want the status after installation is successful but I want it when INSTALL button is clicked.

1 Answers1

0

You can register a broadcast for action PACKAGE_ADDED and even check if the package is installed using PackageManager#getPackageInfo

Refer to these questions:

Edit: After realizing that you are trying to retrieve the click event on the "Install" button instead- I don't think it's possible by any good means. You can change the flow of your app and respond to the success of the installation instead or maybe wait for someone else to pick on this question. They might be some "hacky" way to do this but I'd still not recommend going with it.

Quanta
  • 594
  • 3
  • 24
  • Hi @Qunata...Thanks for your quick help but this is not what I am looking for. I want to get status as soon as the install button is clicked (Refer to the attached image) not after the completion of installation. I am getting the status if user clicks "CANCEL" button but there is no status on clicking "INSTALL" button. – Prashant Sharma Jun 24 '20 at 08:50
  • If you set a Broadcast receiver, you'll achieve exactly what you are looking for. A broadcast is triggered once "Any" package is installed and you check if it was a package you expected. There is no way for you to detect the actual "click" event. – Quanta Jun 24 '20 at 08:55
  • Also, isn't `PackageInstaller.STATUS_SUCCESS` already giving you the success event ? – Quanta Jun 24 '20 at 08:57
  • Yes... PackageInstaller.STATUS_SUCCESS is definitely giving me the status after app is installed but again as I said, I have to detect the INSTALL button only not the installation success/failure. – Prashant Sharma Jun 24 '20 at 09:03
  • I don't think it's possible to do what you're looking for. Please refer to the edit. – Quanta Jun 24 '20 at 09:08
  • I am also thinking the same. I don't see any option to detect the INSTALL button. Anyways thanks for your help. – Prashant Sharma Jun 24 '20 at 09:22
  • @PrashantSharma As you said I am getting the status if user clicks "CANCEL" button. Can you help me in achieving the same. I am not able to get the cancel button click as well. – Saurabh Padwekar Nov 03 '20 at 19:16