karthick
karthick

Reputation: 371

Xamarin forms open view model on notification tap

I am using this code to show notification in notification bar. When the notification is tapped, main activity is launched. Is it possible to launch the view model instead of activity in Xamarin forms app with MvvmCross.

 Intent notificationIntent = new Intent(context,typeof(MainActivity));
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |                                Intent.FLAG_ACTIVITY_SINGLE_TOP);      
   PendingIntent pIntent = PendingIntent.getActivity(context, code,
            notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationManager manager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationCompat.Builder notify = new NotificationCompat.Builder(
            context);

    notify.setContentIntent(pIntent);
    notify.setSmallIcon(R.drawable.app_icon);
    notify.setContentTitle(“Title”);
    manager.notify(reqCode, notify.build());

Upvotes: 2

Views: 1662

Answers (1)

testing
testing

Reputation: 20279

My idea was to make use of PutExtra in combination with MessagingCenter.

First, you show the notification in the notification bar:

Intent intent = new Intent(Forms.Context, typeof(MainActivity));
if (openPage)
{
    intent.SetFlags(ActivityFlags.SingleTop);
    intent.PutExtra("OpenPage", "SomePage");
}

const int pendingIntentId = 0;
PendingIntent pendingIntent = PendingIntent.GetActivity(Forms.Context, pendingIntentId, intent, PendingIntentFlags.OneShot);

var nMgr = (NotificationManager)Android.App.Application.Context.GetSystemService(Context.NotificationService);
Notification.Builder notBuilder = new Notification.Builder(Android.App.Application.Context)
    .SetContentIntent(pendingIntent)
    .SetContentTitle("SomeApp")
    .SetContentText(message)
    .SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
    .SetSmallIcon(Resource.Drawable.ic_launcher)
    .SetAutoCancel(true);

var notification = notBuilder.Build();
nMgr.Notify(0, notification);

In MainActivity.cs you check for the extra content:

protected override void OnNewIntent(Intent intent)
{
    // Send message to the PCL (XF) if a certain page should be opened.
    if (intent.HasExtra("OpenPage"))
    {
        string pageName = intent.GetStringExtra("OpenPage") ?? "None";

        if (pageName != "None")
        {
            var message = new OpenPageMessage { PageName = pageName };
            MessagingCenter.Send(message, Message.Msg_OpenPage);
        }
    }

    base.OnNewIntent(intent);
}

And your central navigation instance (e.g. MainPage), subscribes to this message:

MessagingCenter.Subscribe<Message.OpenPageMessage>(this, Message.Msg_OpenPage, (async) message =>
{
    // Loads a certain page if a message is received

    switch (message.PageName)
    {
        case "SomePage":
            await Navigation.PushModalAsync(new SomePage(), true);
            break;
        default:
            break;
    }
});

Additionally, here is my Message.cs:

public class Message
{
    public const string Msg_OpenPage = "OpenPage";

    public class OpenPageMessage {
        public string PageName { get; set; }
    }
}

With the help of this source.

Edit

There are issues if you have multiple push notifications at a time, where notfications where overwritten. One could use a different requestCode or use FLAG_UPDATE_CURRENT.

Upvotes: 1

Related Questions