Android notifications using MAUI (Part 2 of 10)

In “Android notifications using MAUI (Part 1 of 10)” we created a simple MAUI application and implemented the Android specific code for notifications. In part 2 we mirror Notifications Tutorial Part 2 – ACTION BUTTONS & COLOR – Android Studio Tutorial by adding colour to our notifications along with action buttons.

Overview

We can customize our notifications by changing some parts of the notification’s foreground colour, we can also add buttons (and more) to the notification.

In some cases, when using a foreground service (for example) our application may not no longer be visible, but we want the user to be able to still interact with our application via the notifications. So let’s imagine a stopwatch or better still don’t imagine one, instead go and look at the Android Clock applet, when it goes into the background the notification and foreground service are made available, from here we can see the stop watch running but also press buttons to pause and reset the stop watch, these are action buttons and if your application is designed well, then these can carry out functionality within the foreground service that will appear in the main application when it reappears in the foreground.

Let’s get started

To ensure we’re overwriting our previous application/notification channels etc. uninstall the application it’s it’s on your emulator.

Let’s begin by editing the MainActivity SendOnChannel1 method from the previous post. Here’s what the code should look like

var activityIntent = new Intent(this, typeof(MainActivity));
var contentIntent = PendingIntent.GetActivity(this, 0, activityIntent, 0);

var broadcastIntent = new Intent(this, typeof(NotificationReceiver));
broadcastIntent.PutExtra(MainApplication.ToastMessage, message);
var actionIntent = PendingIntent.GetBroadcast(this, 0, broadcastIntent, PendingIntentFlags.UpdateCurrent);

var notification = new NotificationCompat.Builder(this, MainApplication.Channel1Id)
  .SetSmallIcon(Resource.Drawable.abc_ab_share_pack_mtrl_alpha)
  .SetContentTitle(title)
  .SetContentText(message)
  .SetPriority(NotificationCompat.PriorityHigh)
  .SetCategory(NotificationCompat.CategoryMessage)
  // set the fore colour for the button etc.
  .SetColor(Colors.Red.ToInt())
  .SetContentIntent(contentIntent)
  // when we tap the notification it will close
  .SetAutoCancel(true)
  // only show/update first time
  .SetOnlyAlertOnce(true)
  // can add upto three action buttons
  .AddAction(Resource.Drawable.abc_edit_text_material, "Toast", actionIntent)
  .Build();

_notificationManager.Notify(1, notification);

The first change (the first couple of lines) is that when the user clicks on a notification it does nothing in the original code, but by adding the content intent (as per the code above) we essentially tell the notification that when clicked go to this activity. In our case we create an intent for the MainActivity, but the notification requires a PendingIntent so we create that using PendingIntent.GetActivity. So basically clicking on the notification will bring the application to the foreground.

We’re going to also add a button to our notification, which you can see being set via AddAction (we’re again just reusing an existing resource here), the action/button name is “Toast” and we need to supply an intent for when it’s clicked (null will just not do anything). So we set the actionIntent to the one we created at the top of the method.

The actionIntent is going to be a BroadcastReceiver. So, we first create an intent for typeof(NotificationReceiver) (we’ll look at this type soon) and we add a key/value pair. The key is currently just a const in MainApplication (again for a real world application you’d probably have a class specific for these), it looks like this in MainApplication

public static readonly string ToastMessage = "toastMessage";

Back to the SendOnChannel1 code, we pass the message along with the ToastMessage key, so as you’d probably expect we’re going to popup up a toast message in Android with our message when the action button “Toast” is clicked.

The other changes to this code include setting the foreground colour. Actually this only seems to set the colour of progress bars and actions etc. not the main title and message. We SetAutoCancel to true to close the notification when tapped, we also add SetOnlyAlertOnce so only the first message of high importance on this channel causes the sound to be played and popup display, subsequent messages are just sent to the notification – the is less intrusive especially if you have potentially lots of notification updates on a high priority channel.

Oh, and I almost forgot, we use SetColor to set our colour. Now I’m using the MAUI colours, but ofcourse you may have a colour set as a resource i.e. Resource.Color.notificationColour taken from your Platform/Andourse/Resources/values/colors.xml file.

Adding a BroadcastReceiver

Android would normally require that we add the receiver to the application’s AndroindManifest.xml (application section). But MAUI allows us to declare the received using attributes, so create a new class named NotificationReceiver and it should look like this

[BroadcastReceiver(Enabled = true, Exported = false)]
public class NotificationReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        var message = intent.GetStringExtra(MainApplication.ToastMessage);
        Toast.MakeText(context, message, ToastLength.Short).Show();
    }
}

Beautifully simple. We need to override the OnReceive method, which as the name suggests, receives messages. We get the value for the given key (ToastMessage) and then use the Android Toast code to display a popup message at the bottom of the Android screen). The only other thing to point out is that, as mentioned, we use the BroadcastReceiver attribute to register our receiver.

Code

Code for this an subsequent posts is found on my blog project.