Reputation: 1388
I have an app that has an ongoing notification to help with memorization. I want to be able to dismiss this notification with one of the action button, but I don't want to open the app when the button is hit. I would prefer to use the built-in notification action buttons and not create a RemoteViews object to populate the notification. I saw one post mention using a BroadcastReceiver on this button which is received in my app, and though his tutorial was quite unhelpful, it sounds like this is headed in the right direction.
Intent resultIntent = new Intent(getBaseContext(), Dashboard.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getBaseContext());
stackBuilder.addParentStack(Dashboard.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
Intent cancel = new Intent(getBaseContext(), CancelNotification.class);
stackBuilder.addParentStack(Dashboard.class);
stackBuilder.addNextIntent(cancel);
PendingIntent pendingCancel =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mb = new NotificationCompat.Builder(getBaseContext());
mb.setSmallIcon(R.drawable.cross_icon);
mb.setContentTitle(ref);
mb.setContentText(ver);
mb.setPriority(NotificationCompat.PRIORITY_LOW);
mb.setOngoing(true);
mb.setStyle(new NotificationCompat.BigTextStyle().bigText(ver));
mb.setContentIntent(resultPendingIntent);
mb.addAction(R.drawable.ic_cancel_dark, "Dismiss", pendingCancel);
manager.notify(1, mb.build());
Upvotes: 25
Views: 33270
Reputation: 2377
I have tried using answer from @ramaral , but it is not working as the notificationId
at the onReceive
method always -1
. I have found the solution for this problem by configuring
from
PendingIntent.getBroadcast(context, 0, approvedIntent, 0)
to
PendingIntent.getBroadcast(
context,
notificationId,
approvedIntent,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
Here is an example that you can follow.
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
val notificationId = Random.nextInt()
//Making Approve Intent for Button Action
val approvedIntent = Intent(context,
BroadcastReceiverOuting::class.java).apply {
action = ActionOuting.ACTION_APPROVED.name
putExtra(
Constant.NOTIFICATION_ID,
notificationUid
) //Compulsory to dismiss this notification
putExtra(Constant.STUDENT_IC, studentIc)
putExtra(Constant.OUTING_ID, outingId)
}
val approvedPendingIntent: PendingIntent =
PendingIntent.getBroadcast(
context,
notificationUid,
approvedIntent,
PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)
val notification: Notification =
notificationCompatBuilder
.setStyle(bigTextStyle)
.setContentTitle(title)
.setContentText(description)
.setSmallIcon(R.drawable.ic_logo_128)
.setContentIntent(notifyPendingIntent)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(true)
.addAction(
R.drawable.ic_baseline_approve_check_24,
context.getString(R.string.approve),
approvedPendingIntent
)
.build()
NotificationManagerCompat.from(context.applicationContext).apply {
notify(notificationUid, notification)
}
}
And then at the BroadcastReceiverOuting
override fun onReceive(context: Context?, intent: Intent?) {
if (intent != null && intent.action != null) {
val notificationUid = intent.getIntExtra(Constant.NOTIFICATION_ID, -1)
val studentIC = intent.getStringExtra(Constant.STUDENT_IC)!!
val outingID = intent.getStringExtra(Constant.OUTING_ID)!!
//Do something...
//To dismiss the notification
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancel(notificationUid)
}
}
Lastly, don't forget the AndroidManifest.xml
.
<receiver
android:name=".utils.BroadcastReceiverOuting"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Upvotes: 0
Reputation: 6179
Start with this:
int final NOTIFICATION_ID = 1;
//Create an Intent for the BroadcastReceiver
Intent buttonIntent = new Intent(context, ButtonReceiver.class);
buttonIntent.putExtra("notificationId",NOTIFICATION_ID);
//Create the PendingIntent
PendingIntent btPendingIntent = PendingIntent.getBroadcast(context, 0, buttonIntent,0);
//Pass this PendingIntent to addAction method of Intent Builder
NotificationCompat.Builder mb = new NotificationCompat.Builder(getBaseContext());
.....
.....
.....
mb.addAction(R.drawable.ic_Action, "My Action", btPendingIntent);
manager.notify(NOTIFICATION_ID, mb.build());
Create the BroadcastReceiver:
public class ButtonReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getIntExtra("notificationId", 0);
// Do what you want were.
..............
..............
// if you want cancel notification
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(notificationId);
}
}
If you don´t want show any activity when user click on notification, define the intent passed in setContentIntent
in this way:
PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
......
......
mb.setContentIntent(resultPendingIntent);
To close notification tray when clicked, call setAutoCancel()
with true when building the notification: mb.setAutoCancel(true);
Upvotes: 82
Reputation: 6499
The accepted solution is not working in Android 8.1 and onwards.
Follow the same steps as in the accepted answer, but update this line:
//Create the PendingIntent
PendingIntent btPendingIntent = PendingIntent.getBroadcast(context, 0, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
See also PendingIntent.FLAG_UPDATE_CURRENT
Upvotes: 5