Use the Push Notification payload to open the correct page

First, I am using Xamarin Forms for WP8, iOS and Android apps.

Purpose:

I want to jump to a specific page when toast is clicked depending on the payload information from the toast notification.

I have push notifications using Azure Notification Hubs that are all configurable and working well. I am using MVVMLight and their dependency injection to configure push notifications specifically for each platform.

Each payload must be sent slightly differently due to the different formats required. With each of these, you will notice that I want to send the SignalId in the payload in order to perform various actions required on the receiving device from regular push notifications.

Android

{
  "data" : {
    "msg" : "message in here",
    "signalId" : "id-in-here",
  },
}

      

Ios

{

    "aps" : { "alert" : "message in here" },
    "signalId" : "id-in-here"

}

      

Windows Phone 8

 <?xml version="1.0" encoding="utf-8"?>
 <wp:Notification xmlns:wp="WPNotification">
     <wp:Toast>
          <wp:Text1>category</wp:Text1>
          <wp:Text2>message in here</wp:Text2>
          <wp:Param>?signalId=id-in-here</wp:Param>
     </wp:Toast>
 </wp:Notification>

      

...

Question:

How do I get this information in a Xamarin Forms app and redirect to the appropriate page when the app resumes because the user has clicked on the toast notification?

I want to get some useful information when loading the application and then say yes, this contains SignalId, allows you to redirect to this page.

At the moment, all it does is show the app when the toast notification is clicked. Do I have to do this specifically for the application, or is there a Xamarin Forms way?

Any help was appreciated, even if you only know how to do this for one platform, I might still work on other platforms.

+3


source to share


1 answer


I found a way to do this for all platforms. Windows tested, Android and iOS not.

Windows and iOS are working on toast notification if the app is in the background, or let your code handle it if the app is in the foreground. Android shows toast regardless of app status.

On Windows Phone 8, I need to go to MainPage.xaml.cs and add this override.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        if (this.NavigationContext.QueryString.ContainsKey("signalId"))
        {
            var signalId = this.NavigationContext.QueryString["signalId"];
            var id = Guid.Empty;

            if (signalId != null
                && Guid.TryParse(signalId, out id)
                && id != Guid.Empty)
            {
                this.NavigationContext.QueryString.Clear();
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // Do my navigation to a new page
                });
            }
        }
    }

      

For Android in GcmService

  protected override void OnMessage(Context context, Intent intent)
        {
            Log.Info(Tag, "GCM Message Received!");

            var message = intent.Extras.Get("msg").ToString();
            var signalId = Guid.Empty;

            if (intent.Extras.ContainsKey("signalId"))
            {
                signalId = new Guid(intent.Extras.Get("signalId").ToString());
            }


                // Show notification as usual
                CreateNotification("", message, signalId);


        }

      

Then, in the CreateNotification function, add additional information to the intent.



            var uiIntent = new Intent(this, typeof(MainActivity));

            if (signalId != Guid.Empty)
            {
                uiIntent.PutExtra("SignalId", signalId.ToString());
            }

      

Then in MainActivity.cs override this function

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        if (data.HasExtra("SignalId"))
        {
            Guid signalId = new Guid(data.GetStringExtra("SignalId"));
            if (signalId != Guid.Empty)
            {
                data.RemoveExtra("SignalId");
                // Do you navigation
            }
        }
    }

      

On iOS, you will notice that I have increased the default ProcessNotification ()

  void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
    {
        // Check to see if the dictionary has the aps key.  This is the notification payload you would have sent
        if (null != options && options.ContainsKey(new NSString("aps")))
        {
            //Get the aps dictionary
            var aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;

            var alert = string.Empty;

            //Extract the alert text
            // NOTE: If you're using the simple alert by just specifying 
            // "  aps:{alert:"alert msg here"}  " this will work fine.
            // But if you're using a complex alert with Localization keys, etc., 
            // your "alert" object from the aps dictionary will be another NSDictionary. 
            // Basically the json gets dumped right into a NSDictionary, 
            // so keep that in mind.
            if (aps.ContainsKey(new NSString("alert")))
                alert = ((NSString) aps[new NSString("alert")]).ToString();

            // If this came from the ReceivedRemoteNotification while the app was running,
            // we of course need to manually process things like the sound, badge, and alert.
            if (!fromFinishedLaunching)
            {
                //Manually show an alert
                if (!string.IsNullOrEmpty(alert))
                {
                    var signalId = new Guid(options.ObjectForKey(new NSString("signalId")) as NSString);

                    // Show my own toast with the signalId
                }
            }
        }
    }

      

Then in the FinishedLaunching function check if there is any payload

        // Check if any payload from the push notification
        if (options.ContainsKey("signalId"))
        {
            var signalId = new Guid(options.ObjectForKey(new NSString("signalId")) as NSString);

            // Do the navigation here         
        }

      

+3


source







All Articles