The notification builder

Some tasks take a long time, or events may occur when the user is not using our app. Because some tasks take a long time, we run them in the background. As a result, we need to let the user know when a task is complete, or that some extra information is needed.

Getting ready

If we are going to support Android versions prior to 3.0, we will have to install the Xamarin Support Library v4 NuGet or component into our project.

How to do it...

If an event occurs when the user is not using our app, we can let the user know about it by using a Notification instance from the following steps:

  1. Create the notification using the NotificationCompat.Builder instance:
    var builder = new NotificationCompat.Builder(this)
      .SetSmallIcon(Android.Resource.Drawable.StatNotifySync)
      .SetContentTitle("Simple Notification")
      .SetContentText("Hello World!")
      .SetAutoCancel(true);
  2. Or, if only supporting Android versions 3.0 and above, use the Notification.Builder instance:
    var builder = new Notification.Builder(this)
      .SetSmallIcon(Android.Resource.Drawable.StatNotifySync)
      .SetContentTitle("Simple Notification")
      .SetContentText("Hello World!")
      .SetAutoCancel(true);
  3. Before we display the notification, we need the NotificationManager type and an ID used to reference this notification once displayed:
    const int notificationId = 123;
    var manager = NotificationManager.FromContext(this);
  4. Now we create the actual notification using the Build() method and display it using the Notify() method of the NotificationManager type:
    manager.Notify(notificationId, builder.Build());

Often, we will want to navigate the user to a specific activity in our app, and for this we add a content intent to the notification:

  1. To launch our activity when we tap the notification, we create a PendingIntent instance that holds the Intent instance to launch the activity:
    var intent = new Intent(
      this, typeof(NotificationActivity));
    var pendingIntent = PendingIntent.GetActivity(
      this, 0, intent, PendingIntentFlags.UpdateCurrent);
  2. We then assign this pending intent to the notification by using the SetContentIntent() method:
    builder.SetContentIntent(pendingIntent);

If we want to provide a back stack for when the user presses the back button once the notification activity is shown, we can do so using the TaskStackBuilder type:

  1. First, we need to let Android know what to go back to, and we do this by setting the ParentActivity property of the [Activity] attribute for our notification activity:
    [Activity(..., ParentActivity = typeof(MainActivity))]
  2. If we are supporting versions of Android below 4.1, we also need to add a [MetaData] attribute:
    [MetaData(
      "android.support.PARENT_ACTIVITY",
      Value = "com.xamarincookbook.MainActivity")]
  3. We have to make sure that we also register our parent activity with the same name as the value of the metadata:
    [Register("com.xamarincookbook.MainActivity")]
  4. Finally, we can create the back stack to the Intent instance using the AddNextIntentWithParentStack() method of the TaskStackBuilder type:
    var intent = new Intent(
      this, typeof(NotificationActivity));
    var backStack = TaskStackBuilder.Create(this)
      .AddNextIntentWithParentStack(intent);
    var pendingIntent = backStack.GetPendingIntent(
      0, (int)PendingIntentFlags.UpdateCurrent);

How it works...

Some tasks take a long time and the user will switch to another app while such a task is running. When the task is finished, we may want to let the user know. Or an event may occur in the background while the user is using another app. Regardless of what the user is doing, we can use a Notification instance to display information in the system status bar.

When the user decides that they want to respond to the notification, they can tap it and it will launch right into the activity that relates to the notification. The whole notification could be used as the entry point, with buttons that provide additional actions.

Note

Notifications are used to display information in the notification area and allow the user to respond whenever they want to, if at all.

Almost all notifications provide an action, even if it is just to launch the app or an activity in the app. To do this, we use a PendingIntent instance, which holds the actual Intent instance that we wish to trigger. The PendingIntent instance can hold any Intent instance with any amount of extras or back stacks that will be required to get the user directly to the desired point. We can attach the intent using the SetContentIntent() method of the builder.

Setting the intent is not required, but is both expected and recommended because the user expects that something will happen after tapping the notification. However, if action buttons are used, the intent does not have to be attached to the actual notification but to the action buttons.

Tip

Although optional, an intent is used to launch the app from the notification.

To create the actual Notification instance, we use the NotificationCompat.Builder instance, or if we are only supporting Android versions 3.0 and above, we use Notification.Builder. We construct an instance of the builder and use the many setter methods to create the structure of the notification.

There are three required properties of a notification: the icon, set by SetSmallIcon; the title, set by SetTitle; and the detail text, set by SetContentText. The user also expects that the notification will be removed from the status bar when it is tapped. We could remove this manually, but we can do this automatically by passing true to the SetAutoCancel() method.

Tip

Using auto-cancel removes the need for any extra code to cancel the notification when it is tapped.

When we are ready to display the notification, we use the NotificationManager instance. To obtain the actual notification that is to be displayed, we invoke the Build() method on the builder. We then invoke the Notify() method on the manager with both an ID and the notification. The ID allows us to locate, update, or remove a notification once it has been displayed, if need be.

Unless the notification takes the user to a special activity, we should also specify a back stack on the intent. Without a back stack, the notification will launch the activity, and when the user presses back, the activity will close and return the user to exactly where they were. By specifying a back stack, we can allow the user to navigate upwards, just as if they had entered the app from the home screen.

Tip

The advantage of a back stack is that the navigation path through the app is maintained regardless of the entry point.

The back stack is created by setting the parent activity for the notification activity. We do this by adding attributes to the notification activity, which describe how to get to the parent activity. Typically, we would provide the type of the parent activity for the ParentActivity property of the [Activity] attribute. Because we are supporting versions of Android prior to 4.1, we also add a [MetaData] attribute. This attribute has a string value of the full name of the parent activity as it appears to Android. In order to know what the compiler will use as the name, we need to specify exactly what we want. By adding a [Register] attribute to the parent activity, we can control what the name will be. We then use this name in our notification activity's metadata.

Tip

Both the ParentActivity property of the [Activity] attribute and a [MetaData] attribute must be applied to support the back stack on all versions of Android.

When creating the back stack, we use the TaskStackBuilder type. This type has been around since Android version 3.0, but we use the type from the support library instead. If we do not, the app will crash on older Android versions. Both types work the same, and we use the AddNextIntentWithParentStack() method to attach the intents for both the destination activity and its parents. One difference is that on Android versions prior to 3.0, the back stack is ignored.

Note

The support library provides the TaskStackBuilder type so the app does not crash, but it does not add any functionality.

Once we have built our back stack, we get the PendingIntent instance using the GetPendingIntent() method. We can then pass this pending intent to the notification builder using the SetContentIntent() method.

There's more...

We can also add many features to the notification, such as action buttons using the AddAction() method. To do this, we provide an icon, some text, and a PendingIntent instance. The PendingIntent instance is triggered when the user has tapped a button and we then respond when we receive it. We can also add various extra features such as tickers and vibrations, as well as more information to notifications. All these features can be added using the various setter methods on the Builder object.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset