2

In my app I implemented an update process, by which, if a new version is available, it automatically downloads from my server the new apk and then it tries to install it. I noticed for Android 10 devices I have to use PackageInstaller API (Android 10 - No Activity found to handle Intent): doing so my app correctly starts the installation process.

Here is the code I used:

    try{
        String apkPackageName = BuildConfig.APPLICATION_ID;
        PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        params.setAppPackageName(apkPackageName);
        int sessionId = packageInstaller.createSession(params);
        packageInstaller.registerSessionCallback(new InstallationSessionCallback());
        PackageInstaller.Session session = packageInstaller.openSession(sessionId);
        OutputStream outputStream = session.openWrite(apkPackageName, 0, -1);
        byte[] buffer = new byte[16384];
        int n;
        while ((n = inputStream.read(buffer)) >= 0) {
            outputStream.write(buffer, 0, n);
        }
        session.fsync(os);
        inputStream.close();
        outputStream.close();
        Intent intent = new Intent(context, MainActivity.class);
        intent.setAction("myPackage.ANDROID10_INSTALLATION");
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        IntentSender statusReceiver = pendingIntent.getIntentSender();
        session.commit(statusReceiver);
        session.close();
    }
    catch(Exception e){
        Log.e(LOGTAG, e.toString());
    }

onNewIntent callback:

@Override
protected void onNewIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    String action = "myPackage.ANDROID10_INSTALLATION";
    String intentAction = intent.getAction();
    if (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:
                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();
        }
    }
}

What I want to do is to put my app in foreground, after the installation process has completed. Now I can't achieve that behaviour, because after the installation process, my app disappeares (it goes in background).

In addition, in the onNewIntent callback, the PackageInstaller.STATUS_SUCCESS case is never reached.

Is there a way to obtain what I need?

I mean, I just want to show the same dialog as it appears in the standard apk installation: enter image description here

A M
  • 831
  • 1
  • 14
  • 26

0 Answers0