Reputation: 569
I have a push notification with 2 actions (Accept, Decline). How can I determine which action was actually tapped and then have the notification disappear (acting as if the user has tapped the actual notification and not the action button)? It looks like both action taps go into my OnNewIntent method and I'd like to do different actions based on which one was tapped. My notification is also still showing in the notification bar except the actions (buttons) are no longer displayed. The notification fully goes away when I tap it.
Here's my SendLocalNotification method in FirebaseService (ignore the comments. they're for me):
void SendLocalNotification(string body)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.SingleTop);
intent.PutExtra("OpenPage", "SomePage");
//intent.PutExtra("message", body);
//Unique request code to avoid PendingIntent collision.
var requestCode = new Random().Next();
var pendingIntent = PendingIntent.GetActivity(this, requestCode, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this)
.AddAction(0, "Accept", pendingIntent) // THIS ADDS A BUTTON TO THE NOTIFICATION
.AddAction(0, "Decline", pendingIntent) // THIS ADDS A BUTTON TO THE NOTIFICATION
.SetContentTitle("Load Match")
.SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
.SetContentText(body)
.SetAutoCancel(true)
.SetShowWhen(false)
.SetContentIntent(pendingIntent);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
}
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
And then my OnNewIntent in MainActivity:
protected override void OnNewIntent(Intent intent)
{
if (intent.HasExtra("OpenPage"))
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, "Notification");
}
base.OnNewIntent(intent);
}
EDIT: My OnNewIntent has that logic currently because I was using the MessagingCenter to send a message to a subscriber on a view model and doing a view navigation. Then I discovered Actions and that's how I ended up here trying to do that logic with the notification buttons.
Upvotes: 0
Views: 1121
Reputation: 569
So I was able to figure out what (I think) I needed by following some of what Barel answered as well as some other SO pages and piecing this together.
I'm sure I'll run into some changes I need to make later but, for now, this got me to where I could have 2 actions (Accept, Decline), select either of the action buttons, and then hit some logic where I'm going to implement what I want to do with both actions.
SendLocalNotification method in FirebaseService class:
void SendLocalNotification(string body)
{
//Unique request code to avoid PendingIntent collision.
var requestCode = new Random().Next();
// accept
var acceptIntent = new Intent(this, typeof(MainActivity));
acceptIntent.SetAction("ACCEPT_ACTION");
var pendingIntentAccept = PendingIntent.GetActivity(this, requestCode, acceptIntent, PendingIntentFlags.OneShot);
// decline
var declineIntent = new Intent(this, typeof(MainActivity));
declineIntent.SetAction("DECLINE_ACTION");
var pendingIntentDecline = PendingIntent.GetActivity(this, requestCode, declineIntent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this)
.AddAction(0, "Accept", pendingIntentAccept)
.AddAction(0, "Decline", pendingIntentDecline)
.SetContentTitle("Load Match")
.SetSmallIcon(Resource.Drawable.laundry_basket_icon_15875)
.SetContentText(body)
.SetAutoCancel(true)
.SetShowWhen(false)
.SetContentIntent(pendingIntentAccept)
.SetContentIntent(pendingIntentDecline);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
}
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
And then I had to update my OnNewIntent override in MainActivity. Notice the manager.CancelAll()
. I had to do this to actually remove the notification from my bar after clicking the action:
protected override void OnNewIntent(Intent intent)
{
switch (intent.Action)
{
case "ACCEPT_ACTION":
Console.WriteLine("hit accept action case.");
break;
case "DECLINE_ACTION":
Console.WriteLine("hit decline action case.");
break;
default:
Console.WriteLine("didn't hit either action.");
break;
}
var manager = (NotificationManager)this.GetSystemService(Context.NotificationService);
manager.CancelAll();
base.OnNewIntent(intent);
}
Upvotes: 0
Reputation: 636
Create Nofification with "yes", "no" and "maybe" actions:
//Yes intent
Intent yesReceive = new Intent();
yesReceive.setAction(YES_ACTION);
PendingIntent pendingIntentYes = PendingIntent.getBroadcast(this, 12345, yesReceive, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.calendar_v, "Yes", pendingIntentYes);
//Maybe intent
Intent maybeReceive = new Intent();
maybeReceive.setAction(MAYBE_ACTION);
PendingIntent pendingIntentMaybe = PendingIntent.getBroadcast(this, 12345, maybeReceive, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.calendar_question, "Partly", pendingIntentMaybe);
//No intent
Intent noReceive = new Intent();
noReceive.setAction(NO_ACTION);
PendingIntent pendingIntentNo = PendingIntent.getBroadcast(this, 12345, noReceive, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.calendar_x, "No", pendingIntentNo);
Then create broadcast receiver to called when action clicked:
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(YES_ACTION.equals(action)) {
Log.v("shuffTest","Pressed YES");
} else if(MAYBE_ACTION.equals(action)) {
Log.v("shuffTest","Pressed NO");
} else if(NO_ACTION.equals(action)) {
Log.v("shuffTest","Pressed MAYBE");
}
}
Notice to be appropriate when you sending actions.
Upvotes: 1