Push Notifications Lifecycle

Push notifications are a common feature in mobile apps and if you read my previous post or others you will easily understand how to receive them. Most walk-throughs stop at that point but what do you do after you receive them? As you will find out there are a few scenario’s in different platforms you need to accommodate.

push notifications

Android

Android is the most interesting to handle push notifications, where its handy to have a few tricks up your sleeve. When you are in the foreground in your class which inherited GcmServiceBase, there is an OnMessageReceived method which is called when a push notification is received. When your app is backgrounded it will come through the MainActivity.cs.

androidnotificationlifecycle

In the foreground, you will need to code yourself or use a plugin like Toast Notifications for Xamarin and Windows to show a Snackbar or Notification. You must handle the display of the push notification yourself. When backgrounded, the user opens the app via clicking the notification, you must handle the response in the MainActivity, but while most examples might show you using it in the OnCreate, this actually isn’t a great place to use it.

In your MainActivity.cs set your LaunchMode to SingleTop. This means your MainActivity wont be created again when opened.

[Activity(Label = "Mobile App", Theme = "@style/MainTheme", LaunchMode = LaunchMode.SingleTop)]

Next use the OnNewIntent to handle the notification arguments passed through, instead of OnCreate.

protected override void OnNewIntent(Intent intent)
{
    if (intent != null)
    {
        var message = intent.GetStringExtra("message");

        if (!string.IsNullOrEmpty(message))
        {
              // Do something
        }
    }
 }

WakefulBroadcastReceiver

Unlike other platforms, if your Android app is closed, it will not receive Push Notifications. This is because Android receives push notifications via a service that the app launches. If the app is closed, then the service is not running and hence the app will not receive any push notifications. However, there is a way around this, by implementing a WakefulBroadcastReceiver.

First, add the WakeLock permission in your AndroidManifest.xml.

 <uses-permission android:name="android.permission.WAKE_LOCK" />

Now, add a WakefulBroadcastReceiver.

public class BroadcastReceiver : WakefulBroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var pm = PowerManager.FromContext(context);
        var wakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Reciever Tag");
        wakeLock.Acquire();

        // Handle the notification here. You have an Intent and Context which will contain the information you are after.
        // ....

        // When you are finished
        sWakeLock.Release();
    }
}

 

iOS

In iOS, if the app is in the foreground, a different method is called than when in the app is in the background. ReceivedRemoteNotification is used when the app is backgrounded, DidReceiveRemoteNotification is called when the app is in the foreground.

iosnotificationlifecycle

If the app is in the foreground, it also won’t show a push notification, you have to manually either show an alert or show a notification of your own. For this you might want to look at the Toast Notifications for Xamarin and Windows plugin, or manually send an UNNotificationRequest (iOS 10+) if you want to roll your own.

UWP

Windows is the easiest platform, as a Toast Notification will be displayed if the app is in the foreground and when the app is backgrounded. When a user clicks on the Toast, the OnActivated function will be called in your App.xaml.cs.

uwptoastlifecycle

The args in here are from the launch argument in your toast if you placed any in the notification you sent.

Microsoft MVP | Xamarin MVP | Xamarin Certified Developer |
Exrin MVVM Framework | Xamarin Forms Developer | Melbourne, Australia

Related Posts

10 Comments

  1. Emanuel Nogueiras

    Hi, I am new in xamarin. I have a portable project with android push notifications workin

    But…. when I receive a push in the android project (onMessage) I need to call a void in portable project… and I do not know how to access to it…

    I think of use events or delegates but really I do not know what they are or how to use it

    Do you think you can help me in some way?

  2. Shahriat Hossain

    I am using args as extra like below:

    var jGcmData = new JObject();
    var jData = new JObject();

    jData.Add(“message”, MESSAGE);
    jData.Add(“args”, “1”);
    jGcmData.Add(“to”, “/topics/pushString”);
    jGcmData.Add(“data”, jData);

    and trying to receive using your given code below on MainActivity:

    protected override void OnNewIntent(Intent intent)
    {
    if (intent != null)
    {
    var args = intent.GetStringExtra(“args”);

    if (!string.IsNullOrEmpty(args))
    {
    // Do something
    }
    }
    }

    but here getting args (null)
    can you help me what I am doing wrong?

  3. Philipp

    Hi. Is it correct that you absolutely don’t need any Anotations for your WakefulBroadcastReceiver? No intentFilter? No flags? Nothing?
    Cheers

    1. Adam Pedley

      Your WakefulBroadcastReceiver would normally be the main receiver you use. As such the intent filters of com.google.android.c2dm.intent.RECEIVE and com.google.android.c2dm.intent.REGISTRATION that you would normally use, would be attached to this receiver.

  4. Mario Kielblock

    If you say the WakefulBroadcastReceiver would Normally be the main receiver,
    does that mean I should remove these Classes in my project.

    public class MyBroadcastReceiver : GcmBroadcastReceiverBase

    [Service] // Must use the service tag
    public class PushHandlerService : GcmServiceBase

    I just do not understand how to implement the WakefulBroadcastReceiver into my Xamarin Forms App and the only doc’s I get on it is in the Xamarin.Android section

    1. Adam Pedley

      WakefulBroadcastReceiver is an Android only function, so its not cross-platform, but other platforms handle this differently.

      If I remember correctly, you should keep your existing BroadcastReceiver, and add the Wakeful one as well. The WakefulBroadcastReceiver will only be called when waking, where as the other one will be called when the app is running.

      1. Mario Kielblock

        Thank you, got it semi working, just got to figure how to wake up the app correctly now, as I get ‘App’ stopped responding message on receiving the wakeful message

Leave A Comment?