Notification Actions

Since Android Jelly Bean it has been possible to add up to 3 action buttons at the bottom of your notification, each launching a different PendingIntent:

Building on the example given in the Notification post:

new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
                .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
                .setSmallIcon(R.drawable.ic_app_smallIcon)
                .setLargeIcon(R.drawable.ic_app_largeIcon)
                ... // Code clipped for brevity
                .addAction(firstAction); // Add 1st action, taking a Notification.Action parameter (see method below)
                .addAction(secondAction); // Add 2nd action, taking a Notification.Action parameter
                .setAutoCancel(true); // Notification automatically disappears once clicked
        notificationManager.notify(NOTIFICATION_ID, builder.build()); // Trigger the notification
    }

Typical code to create the first Notification.Action method:

    private static final int IGNORE_NOTIFICATION_PENDING_INTENT_ID = 3418; // Constant declared
    public static NotificationCompat.Action firstAction(Context context) { // Method that returns a Notification.Action object
        Intent intent = new Intent(context, AppIntentService.class); // Sets the Intent to an IntentService class (see below)
        intent.setAction(AppTasks.ACTION_DISMISS_NOTIFICATION); // Sets the action to a predefined String in another class (see below)
        PendingIntent pendingIntent = PendingIntent.getService(context, IGNORE_NOTIFICATION_PENDING_INTENT_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT); // IGNORE_NOTIFICATION_PENDING_INTENT_ID will be a unique ID. Flag set to CANCEL
        NotificationCompat.Action action = new NotificationCompat.Action(R.drawable.ic_app_notification, "Ignore", pendingIntent); // Sets an icon, label and PendingIntent
        return action;
    }

IntentService class:

public class AppIntentService extends IntentService {

    public AppIntentService() {
        super("AppIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String action = intent.getAction(); // Gets the String from the .setAction in the Notification.Action method
        AppTasks.executeTask(this, action); // Calls a method from another class (see below)
    }
}

Additional class:

public class AppTasks {

    public static final String ACTION_DISMISS_NOTIFICATION = "dismiss-notification";

    public static void executeTask(Context context, String action) {
        if (ACTION_DISMISS_NOTIFICATION.equals(action)){ // Takes the action passed in from the IntentService class and, in this case, clears all notifications
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // This code would probably be better in another class
        notificationManager.cancelAll(); // This code would probably be better in another class
        }
    }
}

ud851-Exercises-student\Lesson10-Hydration-Reminder\T10.03

PendingIntent

This configures the permissions for services, private activities and broadcast-protected Intents to be started via Intent from e.g. a notification or another app, even if your app is not currently running. Hence the PendingIntent static methods: getService(), getActivity() or getActivities() and getBroadcast(). Each method requires 4 parameters e.g. for getActivity():

  • context: The Context in which this PendingIntent should start the activity
  • requestCode: Private request code for the sender, unique to this Intent
  • intent: Intent of the activity to be launched
  • flags: May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens

A PendingIntent can be st up as follows:

    private static final int PENDING_INTENT_ID = 58; // Provide unique ID no. for the PendingIntent
    private static PendingIntent contentIntent (Context context) { // In this case we've set up a helper class
        Intent intent = new Intent(context, MainActivity.class); // Create the Intent - this opens the MainActivity
        return PendingIntent.getActivity(context, PENDING_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); // Creates the PendingIntent
    }