下面是我的代码,它使用 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()”之后立即返回 null。根据 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 时不时地不为空,并且会打印所需的数据。