PackageInstaller 失败后不调用 OnNewIntent

OnNewIntent is not called after PackageInstaller failure

我使用此代码安装 APK:

我的 activity 启动模式设置为 SingleTop。我从 OnActivityResult 调用 InstallPackageAndroidQAndAbove(我需要在此之前卸载应用程序,然后检查它是否已在那里卸载)。我还修改了该代码以在创建 PendingIntent 对象期间传递 PendingIntentFlags.UpdateCurrent 标志。问题是当 APK 成功安装或安装程序等待用户操作时,OnNewIntent 总是被正确调用,然后我做了一些事情。但是当用户中止安装时,不会调用 OnNewIntent(尽管偶尔会调用它)。我找不到任何关于这种行为的信息。我怎样才能解决这个问题?或者它可能与我正在调试的设备有关(小米 9T Pro 和基于 Android 10 的 MIUI 12)?

我需要在应用安装失败时显示警告对话框并停止进程。作为一种解决方法,我使用 StartActivityForResult,然后在 OnActivityResult 中等待 5 秒并检查是否安装了应用程序。但是这个解决方法当然是不好的,因为如果安装时间超过 5 秒,那么尽管应用程序本身将被安装,但无论如何都会显示警告对话框。

如你所见,为了确保你的OnNewIntent被调用,你必须在[=14]的创建过程中传递这个标志:PendingIntent.FLAG_UPDATE_CURRENT =] 对象。因此,如果您按照您分享的示例进行操作,则:

PendingIntent pendingIntent = PendingIntent.GetActivity(activity, 0, intent, 0);

应该是这样的:

PendingIntent pendingIntent = PendingIntent.GetActivity(activity, 0, intent, PendingIntentFlags.UpdateCurrent);

我的解决方法比我的问题中描述的要好得多。这仍然是一种解决方法,因为我找不到对这种奇怪行为的解释。

我唯一需要的实际上是通知安装失败。我声明了一个继承 PackageInstaller.SessionCallback 的 class。它看起来像这样:

public class PackageInstallObserver : PackageInstaller.SessionCallback
{
    private PackageInstaller PackageInstaller { get; }
    public event EventHandler InstallFailed;

    public PackageInstallObserver(PackageInstaller packageInstaller) => PackageInstaller = packageInstaller;

    public override void OnActiveChanged(int sessionId, bool active) { }

    public override void OnBadgingChanged(int sessionId) { }

    public override void OnCreated(int sessionId) { }

    public override void OnFinished(int sessionId, bool success)
    {
        PackageInstaller.UnregisterSessionCallback(this);
        PackageInstaller.Dispose();
        if (!success) InstallFailed?.Invoke(this, EventArgs.Empty);
    }

    public override void OnProgressChanged(int sessionId, float progress) { }
}

然后在我的 InstallPackageAndroidQAndAbove 方法中创建该 class 的实例并将其传递给 packageInstaller.RegisterSessionCallback 方法。所以现在 InstallPackageAndroidQAndAbove 看起来像这样:

public void InstallPackageAndroidQAndAbove(Android.Net.Uri apkUri)
{
   var packageInstaller = PackageManager.PackageInstaller;
   var sessionParams = new PackageInstaller.SessionParams(PackageInstallMode.FullInstall);
   int sessionId = packageInstaller.CreateSession(sessionParams);
   var session = packageInstaller.OpenSession(sessionId);

   AddApkToInstallSession(apkUri, session);
        
   // Create an install status receiver.
   var intent = new Intent(this, this.Class);
   intent.SetAction(PACKAGE_INSTALLED_ACTION);
   var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent);
   var statusReceiver = pendingIntent.IntentSender;

   // Create an observer and register it
   var observer = new PackageInstallObserver(packageInstaller);
   observer.InstallFailed += OnInstallFailed; // Subscribe to event
   packageInstaller.RegisterSessionCallback(observer);

   // Commit the session (this will start the installation workflow).
   session.Commit(statusReceiver);
}