首页 > 解决方案 > Android - 使用 PackageInstaller 和 PackageInstaller.Session 静默安装 APK

问题描述

查看 Android 的源代码 (AOSP),installPackage标记为已弃用并检查 Android 的 PackageManager 应用程序,它使用PackageInstaller该类创建一个PackageInstaller.Session实例来执行 APK 的安装。

我正在尝试在我的应用程序中做同样的事情。我使用系统密钥签名,并且确实INSTALL_PACKAGES在清单中包含了权限。

这是我的代码:

    val packageName = "com.spotify.music"
    val inputStream = File(filesDir, "spotify.apk").inputStream()

    // ...

    val packageInstaller = context.packageManager.packageInstaller
    val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
    params.setAppPackageName(packageName)

    val sessionId = packageInstaller.createSession(params)
    val session = packageInstaller.openSession(sessionId)
    val out = session.openWrite("COSU", 0, -1)
    inputStream.copyTo(out)
    session.fsync(out)
    inputStream.close()
    out.close()
    session.commit(null)

但是,我收到以下奇怪的空指针异常:

Error while installing: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.AppOpsManager.checkPackage(int, java.lang.String)' on a null object reference

有人知道这里出了什么问题吗?

标签: androidkotlinandroid-sourceandroid-package-managerssilent-installer

解决方案


你不能null传给session.commit(). 请参阅Android 开发人员的文档。您需要的是一个 IntentSender,它是从 PendingIntent 中获得的,而 PendingIntent 又应包含您的应用程序可以接收的意图(可以在 Activity、Service 或 BroadcastReceiver 中)。

提交会话时,结果将作为附加内容包含在接收到的意图中。


推荐阅读