locked
UWP App freeze if it is launched by the toast notification RRS feed

  • Question

  • User385018 posted

    Hi all! I have found an issue about the freeze of my UWP App at launch when it is launched by tap the toast notification. This happen only when the xml of the toast notification use the template ToastGeneric. Using another template, this issue doesn't happen.

    Have someboby faced this issue with UWP App and toast notification?

    Here some code: const string ToastHeroImageTemplate = "<toast launch =\"{0}\">" + " <visual>" + " <binding template=\"ToastGeneric\">" + " <image id=\"2\" placement=\"appLogoOverride\" src=\"{1}\"/>" + " <text id=\"1\">{2}</text>" + " <text id=\"2\">{3}</text>" + " <image placement=\"hero\" id=\"1\" src=\"{4}\"/>" + " </binding>" + " </visual>" + "</toast>";

    public static void SendNotification(string title, string message, string launchArgs, string heroImage)
    {
        const string logo = "ms-appx:///Assets/AboutLogo.png";
    
        try
        {
            XmlDocument toastXml;
            if (string.IsNullOrEmpty(heroImage))
            {
                // --> This always works fine <--
                toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastImageAndText02);
    
                XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
                toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode(title));
                toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(message));
    
                XmlNodeList toastImageNodeList = toastXml.GetElementsByTagName("image");
                toastImageNodeList.Item(0).Attributes.GetNamedItem("id").NodeValue = "1";
                toastImageNodeList.Item(0).Attributes.GetNamedItem("src").NodeValue = logo;
    
                if (!string.IsNullOrEmpty(launchArgs))
                    ((XmlElement)toastXml.SelectSingleNode("/toast")).SetAttribute("launch", launchArgs);
            }
            else
            {
                // --> This doesn't work if the App is closed <--
                toastXml = new XmlDocument();
                toastXml.LoadXml(string.Format(ToastHeroImageTemplate,
                    launchArgs.Replace("\"", "&quot;"),
                    logo,
                    title, message,
                    heroImage));
            }
    
            ToastNotification toast = new ToastNotification(toastXml);
            ToastNotificationManager.CreateToastNotifier().Show(toast);
        }
        catch (Exception Ex)
        {
            Debug.WriteLine("Unable to create toast notification. Error: " + Ex.Message);
        }
    }
    

    Thank you

    Saturday, June 6, 2020 10:45 PM

Answers

  • User371688 posted

    You can try to recheck if the following code is triggered.

    // Ensure the current window is active
    Window.Current.Activate();
    

    Besides, you can also check to see if there are any synchronization operations that affect the Ui thread which cause the OnAppear is freezed.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 11, 2020 2:36 AM

All replies

  • User371688 posted

    You need to override OnActivated in App.Xaml.cs, and you will get ToastNotificationActivatedEventArgs in OnActivated method like the follow. For more please refer Send a local toast notification

    protected override void OnActivated(IActivatedEventArgs e)
    {
        // Get the root frame
        Frame rootFrame = Window.Current.Content as Frame;
    
        // TODO: Initialize root frame just like in OnLaunched
    
        // Handle toast activation
        if (e is ToastNotificationActivatedEventArgs)
        {
            var toastActivationArgs = e as ToastNotificationActivatedEventArgs;
    
            // Parse the query string (using QueryString.NET)
            QueryString args = QueryString.Parse(toastActivationArgs.Argument);
    
            // See what action is being requested 
            switch (args["action"])
            {
                // Open the image
                case "viewImage":
    
                    // The URL retrieved from the toast args
                    string imageUrl = args["imageUrl"];
    
                    // If we're already viewing that image, do nothing
                    if (rootFrame.Content is ImagePage && (rootFrame.Content as ImagePage).ImageUrl.Equals(imageUrl))
                        break;
    
                    // Otherwise navigate to view it
                    rootFrame.Navigate(typeof(ImagePage), imageUrl);
                    break;
    
    
                // Open the conversation
                case "viewConversation":
    
                    // The conversation ID retrieved from the toast args
                    int conversationId = int.Parse(args["conversationId"]);
    
                    // If we're already viewing that conversation, do nothing
                    if (rootFrame.Content is ConversationPage && (rootFrame.Content as ConversationPage).ConversationId == conversationId)
                        break;
    
                    // Otherwise navigate to view it
                    rootFrame.Navigate(typeof(ConversationPage), conversationId);
                    break;
            }
    
            // If we're loading the app for the first time, place the main page on
            // the back stack so that user can go back after they've been
            // navigated to the specific page
            if (rootFrame.BackStack.Count == 0)
                rootFrame.BackStack.Add(new PageStackEntry(typeof(MainPage), null, null));
        }
    
        // TODO: Handle other types of activation
    
        // Ensure the current window is active
        Window.Current.Activate();
    }
    
    Monday, June 8, 2020 7:27 AM
  • User385018 posted

    Hi jezh, thank you for your answer!

    I know how to handle the request from a local toast notification. What I have found is that the App freezes (I see the window with only the logo and the background, nothing else) only if I use a ToastGeneric template. I have implemented a log to file in order to check where the process stops and I have seen that the flow stops in the OnAppear function of the MainPage... I have also received the argument of the launch attribute... so seem to be all fine about the OnActivated.

    I'm starting to think that the other binding templates push the App to follow the correct workflow, while there is a different behaviour with the ToastGeneric template. :(

    Thank you

    Monday, June 8, 2020 9:18 PM
  • User371688 posted

    You can try to recheck if the following code is triggered.

    // Ensure the current window is active
    Window.Current.Activate();
    

    Besides, you can also check to see if there are any synchronization operations that affect the Ui thread which cause the OnAppear is freezed.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, June 11, 2020 2:36 AM
  • User385018 posted

    Thank you jezh! You have helped me to overcome to the issue. Yes, you are right... Window.Current.Activate() was missing in one case for my situation. I have made sure to call that and now it works fine.

    I have understand now what is the difference between the two behaviours: the local toast notification with GenericToast template is handled by OnActivated. The local toast notification with another template (for example, the ToastImageAndText02 template) is handled by OnLaunched ( :o ). I didn't think that it worked in this manner.

    Thursday, June 11, 2020 9:34 PM
  • User371688 posted

    Congrats, and have a nice day! :)

    Friday, June 12, 2020 1:16 AM