【问题标题】:Android - Install APK silently with PackageInstaller and PackageInstaller.SessionAndroid - 使用 PackageInstaller 和 PackageInstaller.Session 静默安装 APK
【发布时间】:2018-07-27 17:34:06
【问题描述】:

查看 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

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

【问题讨论】:

  • 查看PackageInstallerService 的来源,它会在系统启动时获取对mContext.getSystemService(AppOpsManager.class) 的引用。但在你的情况下它是空的。你说你有系统签名。您是否正在构建自定义 ROM?您是否删除/禁用了应用程序操作服务?在您尝试安装时系统是否已完全准备好?这是什么版本的安卓?

标签: android kotlin android-source android-package-managers silent-installer


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    下面的 sn-p 应该适合你(我没有测试它,但更欢迎你调试它并编辑任何必要的更改)。

    方法参数:

    • context - 你的应用程序的上下文
    • installSessionId - 用于标识安装会话的字符串
    • packageName - 您要安装的包名(例如 com.my.package)
    • apkStream - 保存 APK 文件数据的输入流。

    代码如下:

    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class PackageInstaller {
    
        public static void installPackage(Context context, String installSessionId,
                                          String packageName,
                                          InputStream apkStream) throws IOException {
            PackageManager packageManger = context.getPackageManager();
            android.content.pm.PackageInstaller packageInstaller = 
                    packageManger.getPackageInstaller();
            PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
            params.setAppPackageName(packageName);
            android.content.pm.PackageInstaller.Session session = null;
            try {
                int sessionId = packageInstaller.createSession(params);
                session = packageInstaller.openSession(sessionId);
                OutputStream out = session.openWrite(installSessionId, 0, -1);
                byte buffer[] = new byte[1024];
                int length;
                int count = 0;
                while ((length = apkStream.read(buffer)) != -1) {
                    out.write(buffer, 0, length);
                    count += length;
                }
                session.fsync(out);
                out.close();
    
                Intent intent = new Intent(Intent.ACTION_PACKAGE_ADDED);
    
                session.commit(PendingIntent.getBroadcast(context, sessionId,
                        intent, PendingIntent.FLAG_UPDATE_CURRENT).getIntentSender());
            } finally {
                if (session != null) {
                    session.close();
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      相关资源
      最近更新 更多