简体   繁体   中英

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

Note: I have only tested this using the emulator, and pushing toasts using the built in functionality. I am assuming this isn't an emulator issue.

I followed this guide in order to intercept push toast notifications while the app is running. However, I only want to suppress the toast notification when the app is in the foreground. It should still display when another app is in the foreground. So I wrote the following handler in App.xaml.cs (and subscribed to the PushNotificationReceived event):

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();
                    });
            }
        }
    }

So this works, in the sense that I only see the "toast canceled" message when the app was in the foreground when receiving the push notification. When I'm on the start screen or somewhere else I always get the toast. This is good. However, when the app is in the foreground, sometimes (usually after sending the second push) the toast shows up anyway (even though "Toast canceled" displays). But sometimes it doesn't. It's rather inconsistent.

This is leading me to believe that due to the await, sometimes the toast gets through before the code gets run on the UI thread to check whether the app is visible or not. However, I can't access Window.Current.Visible from here without using the dispatcher. I even tried CoreApplication.MainView.CoreWindow.Visible but that gives me "interface marshalled for different thread etc" exception. Speaking of which, I don't understand how CoreApplication.MainView.CoreWindow.Dispatcher can be called from anywhere but CoreApplication.MainView.CoreWindow.Visible not? How does that even work.

Anyway, how do I fix this? I would like to keep this within App.xaml.cs because I have a number of pages in this app, but this content dialog needs to be shown no matter which page the user is on, and without the user being redirected to a different page. However, I am of course open for new suggestions.

I fixed this as per Kai Brummund's suggestion by using a simple boolean toggle in the App class, and subscribing to the VisibilityChanged event like so:

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;
}

That way I can use APP_VISIBLE to suppress the popup without having to use the dispatcher and the toast is suppressed immediately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM