仅当 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.Dispatcher
而 CoreApplication.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 会立即被抑制。
注意:我只使用模拟器测试过这个,并使用内置功能推送祝酒词。我假设这不是模拟器问题。
我关注 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.Dispatcher
而 CoreApplication.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 会立即被抑制。