Почему результаты PackageInstaller.getSessionInfo противоречивы? - PullRequest
0 голосов
/ 20 апреля 2020

Ниже приведен мой код, который использует PackageInstaller для установки APK, который я скачал с моего сервера.

public static final String ACTION_INSTALL_COMPLETE = BuildConfig.APPLICATION_ID + ".INSTALL_COMPLETE";
private void installApk(String apkFilePath) {
    try {
        // Create package manager installation params
        final PackageInstaller pkgInstaller = getBaseContext().getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);

        // Create session callback for monitoring progress
        pkgInstaller.registerSessionCallback(new PackageInstaller.SessionCallback() {
            static final String PKG_LOG_TAG = "pkg-install-status";

            @Override
            public void onCreated(int sID) {
                Log.e(PKG_LOG_TAG, "Session created: " + sID);
                PackageInstaller.SessionInfo sessionInfo = pkgInstaller.getSessionInfo(sID);
                if (sessionInfo != null) {
                    Log.e(PKG_LOG_TAG, "Installing package name: " + sessionInfo.getAppPackageName());
                }
                else {
                    Log.e(PKG_LOG_TAG, "Session does not exist: " + sID);
                }
            }

            @Override
            public void onBadgingChanged(int sID) {
                Log.e(PKG_LOG_TAG, "Badging Changed: " + sID);
            }

            @Override
            public void onActiveChanged(int sID, boolean active) {
                Log.e(PKG_LOG_TAG, "Active Changed: " + sID + ", active=" + active);
                PackageInstaller.SessionInfo sessionInfo = pkgInstaller.getSessionInfo(sID);
                if (sessionInfo != null) {
                    Log.e(PKG_LOG_TAG, "Installing package name: " + sessionInfo.getAppPackageName());
                }
            }

            @Override
            public void onProgressChanged(int sID, float progress) {
                Log.e(PKG_LOG_TAG, "Progress changed: " + sID + ", progress=" + progress);
                PackageInstaller.SessionInfo sessionInfo = pkgInstaller.getSessionInfo(sID);
                if (sessionInfo != null) {
                    Log.e(PKG_LOG_TAG, "Installing package name: " + sessionInfo.getAppPackageName());
                }
            }

            @Override
            public void onFinished(int sID, boolean success) {
                if (!success) {
                    // Print error details
                    Log.e(PKG_LOG_TAG, "Session failed: " + sID);
                    PackageInstaller.SessionInfo sessionInfo = pkgInstaller.getSessionInfo(sID);
                    if (sessionInfo != null) {
                        if (sessionInfo.isStaged())
                            Log.e(PKG_LOG_TAG, sessionInfo.getStagedSessionErrorCode() + " -- " + sessionInfo.getStagedSessionErrorMessage());
                    }
                }
            }
        });

        // Create package manager installation session
        int sessionId = pkgInstaller.createSession(params);
        PackageInstaller.Session session = pkgInstaller.openSession(sessionId);

        // Stream downloaded APK file to package manager session
        InputStream in = new FileInputStream(apkFilePath);
        OutputStream out = session.openWrite("update_session", 0, -1);
        byte[] buffer = new byte[65536];
        int bytesRead = in.read(buffer);
        while (bytesRead != -1) {
            out.write(buffer, 0, bytesRead);
            bytesRead = in.read(buffer);
        }

        // Close streams
        session.fsync(out);
        out.close();
        in.close();

        // Close session
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, sessionId, new Intent(ACTION_INSTALL_COMPLETE),0);
        session.commit(pendingIntent.getIntentSender());
        session.close();
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }
}

Вывод, который я получаю, указывает на то, что был создан правильный SessionID, но сразу после этого 'getSessionInfo () 'возвращает ноль. Согласно официальной документации Android, это означает, что рассматриваемый SessionID не существует. Но как это может быть, когда я нахожусь в обработчике обратного вызова для рассматриваемой сессии? Обратите внимание, что это происходит для всех обратных вызовов, а не только для Create.

system_process W/PackageManager: installPackageLI
E/pkg-install-status: Session created: 676341822
E/pkg-install-status: Session does not exist: 676341822
E/pkg-install-status: Active Changed: 676341822, active=true
E/pkg-install-status: Progress changed: 676341822, progress=0.8
E/pkg-install-status: Progress changed: 676341822, progress=0.90000004
E/pkg-install-status: Session failed: 676341822

И вот странная часть - время от времени sessionInfo НЕ имеет значение null, и требуемые данные печатаются.

...