仅当 App 在前台时,如何抑制推送吐司通知?

How to suppress push toast notification only when App in foreground?

注意:我只使用模拟器测试过这个,并使用内置功能推送祝酒词。我假设这不是模拟器问题。

我关注 this guide 是为了在应用 运行ning 时拦截推送吐司通知。但是,我只想在应用程序位于前台时抑制吐司通知。当另一个应用程序位于前台时,它仍应显示。所以我在 App.xaml.cs 中编写了以下处理程序(并订阅了 PushNotificationReceived 事件):

private async void OnPushNotification(PushNotificationChannel sender, PushNotificationReceivedEventArgs e)
    {
        string msg = "";
        if (e.NotificationType == PushNotificationType.Toast)
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    if (Window.Current.Visible)
                    {
                        msg += " Toast canceled.";
                        e.ToastNotification.SuppressPopup = true;
                    }
                });

            if (true) // actually determines if it's a certain type of toast
            {
                await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
                    {
                        ConfirmationContentDialog confirmationDialog = new ConfirmationContentDialog();
                        confirmationDialog.SetMessage("Please confirm that you like turtles." + msg);
                        await confirmationDialog.ShowAsync();
                    });
            }
        }
    }

所以这是有效的,因为当应用程序在前台接收推送通知时,我只看到 "toast canceled" 消息。当我在开始屏幕或其他地方时,我总是得到祝酒词。这很好。但是,当应用程序位于前台时,有时(通常在发送第二次推送之后)toast 无论如何都会显示(即使 "Toast canceled" 显示)。但有时它不会。比较矛盾。

这让我相信,由于等待,有时 toast 在 UI 线程上的代码获取 运行 之前完成,以检查应用程序是否可见。但是,如果不使用调度程序,我无法从这里访问 Window.Current.Visible。我什至尝试了 CoreApplication.MainView.CoreWindow.Visible 但这给了我 "interface marshalled for different thread etc" 异常。说到这里,我不明白如何从任何地方调用 CoreApplication.MainView.CoreWindow.DispatcherCoreApplication.MainView.CoreWindow.Visible 却不行?那是如何工作的。

无论如何,我该如何解决这个问题?我想将其保留在 App.xaml.cs 内,因为我在该应用程序中有多个页面,但无论用户在哪个页面上,都需要显示此内容对话框,并且不会将用户重定向到其他页面.不过,我当然愿意接受新的建议。

我根据 Kai Brummund 的建议修复了此问题,方法是在应用程序 class 中使用简单的布尔切换,并像这样订阅 VisibilityChanged 事件:

private bool APP_VISIBLE = true;

protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
    // Stuff put here by Visual Studio

    Window.Current.VisibilityChanged += OnVisibilityChanged;

    Window.Current.Activate();
}

private void OnVisibilityChanged(object sender, VisibilityChangedEventArgs e)
{
    if (e.Visible)
        APP_VISIBLE = true;
    else
        APP_VISIBLE = false;
}

这样我就可以使用 APP_VISIBLE 来抑制弹出窗口而无需使用调度程序,并且 toast 会立即被抑制。