4

Edit: I added a solution for API level 29 or later. However, this does not solve my problem.

I would appreciate if someone come up with a method for API level 28 or before.

Original question:

I am using following code to install apks:

final int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
OutputStream out = session.openWrite("COSU", 0, -1);
FileInputStream in = new FileInputStream(apkPath);
byte[] buffer = new byte[4*1024];
int c;
while ((c = in.read(buffer)) != -1) {
    out.write(buffer, 0, c);
}
session.fsync(out);
in.close();
out.close();

packageInstaller.registerSessionCallback(new PackageInstaller.SessionCallback() {
    @Override
    public void onCreated(int sessionid) {
        Log.i(TAG, "onCreated: installer created");
    }

    // ... other handlers

    @Override
    public void onFinished(int sessionid, boolean success) {
        if(sessionid != sessionId)
            return;

        if(success)
        {
            Log.i(TAG, "onFinished: installation successfull");
        }
        else
        {
            Log.i(TAG, "onFinished: installation failed");
        }
    }
});

session.commit(PendingIntent.getBroadcast( common.appContext, sessionId,
        new Intent("android.intent.action.MAIN"), 0).getIntentSender());

It works as I expected. However, I want to get the reason why it failed when it did.

'success' parameter on onFinished handler is just a boolean and does not tell much. Reading the documentation, I understand that there are status codes which can be used for this ( like STATUS_FAILURE_STORAGE, STATUS_FAILURE_INCOMPATIBLE ...), but I couldn't find a documentation or example showing how to get a status code when it fails.

Note: This works without a UI, thus I cannot use examples using visible activities.

t.m.
  • 1,430
  • 16
  • 29
  • I'm having the same issue. Did you ever figure out how to get a better error code out of it? – Bungles Apr 20 '20 at 01:08
  • No. But as I said, msg.arg2 in the PackageInstaller is the error code, 0 being success. If you are ok with modifying android code in your project you can change case MSG_SESSION_FINISHED to send this error code. – t.m. Apr 20 '20 at 05:57
  • Did you try with onNewIntent? https://stackoverflow.com/questions/62550539/how-to-detect-if-user-has-confirmed-for-installation-in-packageinstaller-androi – AndroMen Aug 28 '20 at 11:26
  • Thanks, but as I said, I cannot use examples using visible activities. I need to install updates without user interaction. – t.m. Aug 28 '20 at 12:55

1 Answers1

0

For api level 29 getStagedSessionErrorCode() and getStagedSessionErrorMessage() functions are added. So you can do something like:

Log.e(TAG, packageInstaller.getSessionInfo(installerSessionId).getStagedSessionErrorMessage());
t.m.
  • 1,430
  • 16
  • 29