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

Notifications

How to create the ever-essential Notification. You can also add Notification Actions. Notifications are also intrinsic to the concept of Foreground Services e.g. a music app that persists controls in the notification shade.

Notification channels are a means of categorising your notifications so that users have fine grained control over which notifications they receive and which they deactivate (rather than having to decide all or nothing). An example would be to have separate notification channels for essential information and promotional offers:

A Notification can be set up as follows:

public static void appNotification (Context context) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Get the NotificationManager system service
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // For Oreo and above we create a notification channel
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Awesome App", NotificationManager.IMPORTANCE_HIGH); // Set a unique ID for the channel, give it a name that will be displayed in the notification. and set the importance
            notificationManager.createNotificationChannel(notificationChannel); // Get the NotificationManager to create the channel
        }
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) // NotificationCompat provides functionality to replace deprecated Notification methods and maintain backwards compatibility
                .setColor(ContextCompat.getColor(context, R.color.colorPrimary)) // Sets the background colour of the notification. ContextCompat provides functionality to replace deprecated Context methods and maintain backwards compatibility
                .setSmallIcon(R.drawable.ic_app_smallIcon) // Sets the small icon drawable which will appear in the status bar
                .setLargeIcon(aBitmap) // Sets the large icon bitmap which will appear in the notification content view
                .setContentTitle(context.getString(R.string.notification_title)) // Sets the title
                .setContentText(context.getString(R.string.notification_body)) // Sets the text
                .setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(R.string.notification_body))) // Sets the style of the text
                .setDefaults(Notification.DEFAULT_VIBRATE) // Set the defaults - Notification.DEFAULT_SOUND, Notification.DEFAULT_VIBRATE, Notification.DEFAULT_LIGHTS. Or for all default values, use Notification.DEFAULT_ALL
                .setContentIntent(makePendingIntent(context)) // Feed in the PendingIntent (see method below)
                .setAutoCancel(true); // Notification automatically disappears once clicked
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O && Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) { // For some build versions the priority needs to be set
            builder.setPriority(NotificationCompat.PRIORITY_HIGH);
        notificationManager.notify(NOTIFICATION_ID, builder.build()); // Trigger the notification
    }
    private static PendingIntent makePendingIntent (Context context) {
        Intent intent = new Intent(context, MainActivity.class);
        return PendingIntent.getActivity(context, PENDING_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

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