Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Forms - Processing a Notification Click

I have a Xamarin Forms application which raises an Android Notification but I'm having trouble creating a simple page that will interact with the user when they click the Notification. I understand that in Xamarin.Forms there is only 1 activity and so the pending Intent must be to that mainActivity

I have set the LaunchMode to SingleTop and and Intent Filter to match the Intent name used in the pendingIntent

Now when I click the Notification I do get routed to the OnResume of the MainActivity but I don't understand how to: 1) Recognise that I am in this activity because of the notification click - I tried adding an Extra to the pending Intent but it is not there when I inspect this.Intent.Extras 2) Even if I know that I'm in the activity due to the notification click, how do I launch a specific page from the Activity. I'm new to Xamarin but I can't see how to navigate to a Content Page or access the Navigation Stack.

This must be a really common use case but I can't find anything relevant.

like image 908
Nick Jones Avatar asked Mar 18 '18 18:03

Nick Jones


1 Answers

Ensure the you have set LaunchMode.SingleTop on your MainActivity:

LaunchMode.SingleTop

[Activity(~~~, LaunchMode = LaunchMode.SingleTop, ~~~]
public class MainActivity
{
   ~~~~

In your MainActivity (the FormsAppCompatActivity subclass) add a OnNewIntent override:

OnNewIntent:

protected override void OnNewIntent(Intent intent)
{
    base.OnNewIntent(intent);
    NotificationClickedOn(intent);
}

Now you can check the intent.Action / intent.HasExtra to determine if it is your notification that was send and thus process it. With Xamarin.Forms the easiest would be to use MessagingCenter to send a message that is subscribed to within your .NetStd/PCL Xamarin.Forms code base.

NotificationClickedOn:

void NotificationClickedOn(Intent intent)
{
    if (intent.Action == "ASushiNotification" && intent.HasExtra("MessageFromSushiHangover"))
    {
        /// Do something now that you know the user clicked on the notification...

        var notificationMessage = intent.Extras.GetString("MessageFromSushiHangover");
        var winnerToast = Toast.MakeText(this, $"{notificationMessage}.\n\nšŸ£ Please send 2 BitCoins to SushiHangover to process your winning ticket! šŸ£", ToastLength.Long);
        winnerToast.SetGravity(Android.Views.GravityFlags.Center, 0, 0);
        winnerToast.Show();
    }
}

Send notification example:

void SendNotifacation()
{
    var title = "Winner, Winner, Chicken Dinner";
    var message = "You just won a million StackOverflow reputation points";

    var intent = new Intent(BaseContext, typeof(MainActivity));
    intent.SetAction("ASushiNotification");
    intent.PutExtra("MessageFromSushiHangover", message);
    var pending = PendingIntent.GetActivity(BaseContext, 0, intent, PendingIntentFlags.CancelCurrent);

    using (var notificationManager = NotificationManager.FromContext(BaseContext))
    {
        Notification notification;
        if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.O)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            notification = new Notification.Builder(BaseContext)
                                                        .SetContentTitle(title)
                                                        .SetContentText(message)
                                                        .SetAutoCancel(true)
                                                        .SetSmallIcon(Resource.Drawable.icon)
                                                        .SetDefaults(NotificationDefaults.All)
                                                        .SetContentIntent(pending)
                                                        .Build();
#pragma warning restore CS0618 // Type or member is obsolete
        }
        else
        {
            var myUrgentChannel = BaseContext.PackageName;
            const string channelName = "Messages from SushiHangover";

            NotificationChannel channel;
            channel = notificationManager.GetNotificationChannel(myUrgentChannel);
            if (channel == null)
            {
                channel = new NotificationChannel(myUrgentChannel, channelName, NotificationImportance.High);
                channel.EnableVibration(true);
                channel.EnableLights(true);
                channel.SetSound(
                    RingtoneManager.GetDefaultUri(RingtoneType.Notification),
                    new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).Build()
                );
                channel.LockscreenVisibility = NotificationVisibility.Public;
                notificationManager.CreateNotificationChannel(channel);
            }
            channel?.Dispose();

            notification = new Notification.Builder(BaseContext)
                                                        .SetChannelId(myUrgentChannel)
                                                        .SetContentTitle(title)
                                                        .SetContentText(message)
                                                        .SetAutoCancel(true)
                                                        .SetSmallIcon(Resource.Drawable.icon)
                                                        .SetContentIntent(pending)
                                                        .Build();
        }
        notificationManager.Notify(1331, notification);
        notification.Dispose();
    }
}
like image 85
SushiHangover Avatar answered Oct 23 '22 06:10

SushiHangover