【问题标题】:OnNewIntent is not called after PackageInstaller failurePackageInstaller 失败后不调用 OnNewIntent
【发布时间】:2020-12-31 11:20:36
【问题描述】:

我使用此代码安装 APK:https://stackoverflow.com/a/61889386/14152249

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

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

【问题讨论】:

    标签: c# android xamarin xamarin.android android-install-apk


    【解决方案1】:

    如您所见here,为了确保您的OnNewIntent 被调用,您必须在创建PendingIntent 对象期间传递此标志:PendingIntent.FLAG_UPDATE_CURRENT。因此,如果您遵循您分享的示例,则:

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

    应该是这样的:

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

    【讨论】:

    • 哦,对不起,我忘了在我的问题中提到我实际上通过了这个标志。我将编辑我的问题以包含此信息。
    【解决方案2】:

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

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

    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 方法中创建该类的一个实例并将其传递给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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-21
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多