Written by Adrian Kremski
Android Developer
Published November 17, 2016

Notifications: From zero to hero Android N* – part 3/3

Android Nougat is here and it’s time to learn how to set up the notifications in this version of the system. The bundled notifications and the possibility of replying to them made them even more useful!

The final article of “Notifications: From zero to hero Android N*” series guides you through Android N. In case you missed the previous ones, here you go:

1. If you are a newbie to the Android notifications, here are the very essentials you need to know to build them for the Android Platform. Including the definition itself, just to let you start the proper way.

2. A notifications guide for all developers who already got the basics. You will learn how to become a pro of the Android notifications. It covers Android 5 and 6.

1. Replying to notifications

Sometimes opening the whole app to the user so that he/she could react to the notification can be an overkill. To avoid that kind of situations, users can now respond to the notifications directly (starting in Android 7.0).

To make this happen, first, we have to use RemoteInput.Builder which will be used to extract the text input from the user.

 
String KEY = "reply_input_key";
RemoteInput remoteInput = new RemoteInput.Builder(KEY)
    .setLabel("Reply me")
    .build();

Secondly, we need to specify an action which will be triggered after user’s response (in this example we are going to start the IntentService instance to handle the response).

 
Intent intent = new Intent(this, ReplyToEmailService.class);
intent.putExtra("ID", notificationId);

NotificationCompat.Action action = new NotificationCompat.Action.Builder(android.R.drawable.ic_dialog_email,
    "Reply", PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
    .addRemoteInput(remoteInput)
    .build();

And then we trigger the notification.

 
Notification newMessageNotification = new NotificationCompat.Builder(this)
    .setSmallIcon(android.R.drawable.ic_dialog_alert)
    .setContentTitle("New email")
    .setContentText("Content of new email")
    .addAction(action).build();

notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, newMessageNotification);

The last thing to do is to handle the input from the user.

 
public class ReplyToEmailService extends IntentService {

    public ReplyToEmailService() {
        super(ReplyToEmailService.class.toString());
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(workIntent);
        if (remoteInput != null) {
            String userInput = remoteInput.getCharSequence(AndroidNNotifications.REPLY_KEY).toString();

            try {
                Thread.sleep(3000); // Only for testing
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Notification messageDeliveredNotification = new NotificationCompat.Builder(this)
                    .setSmallIcon(android.R.drawable.ic_dialog_alert)
                    .setContentTitle("Message delivered")
                    .setContentText(userInput)
                    .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, AndroidNNotifications.class), PendingIntent.FLAG_UPDATE_CURRENT))
                    .build();

            ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(workIntent.getIntExtra("ID", -1), messageDeliveredNotification);
        }
    }
}

Result

ezgif.com-resize

2. Bundled notifications

Another cool feature introduced in Android N are bundled notifications. It means that you can now group your messages by their type (consider for example a list of received email messages).

Example:

 

String GROUP_KEY = "group_key";
        
Notification summaryNotification =
    new NotificationCompat.Builder(this)
        .setSmallIcon(android.R.drawable.ic_dialog_alert)
        .setContentTitle("5 New emails")
        .setGroup(GROUP_KEY)
        .setGroupSummary(true)
        .setContentText("You have 5 new emails").build();

notificationManager.notify(notificationId, summaryNotification);

for (int id = 1; id < 5; ++id) {
    RemoteInput remoteInput = new RemoteInput.Builder(REPLY_KEY)
        .setLabel("Reply me")
        .build();

    Intent intentWithDefinedAction = new Intent(this, ReplyToEmailService.class);
    intentWithDefinedAction.putExtra("ID", id);

    NotificationCompat.Action action = new NotificationCompat.Action.Builder(android.R.drawable.ic_dialog_email,
        "Reply", PendingIntent.getService(this, id, intentWithDefinedAction,        PendingIntent.FLAG_UPDATE_CURRENT))
        .addRemoteInput(remoteInput)
        .build();

    Notification newMessageNotification = new NotificationCompat.Builder(this)
        .setSmallIcon(android.R.drawable.ic_dialog_alert)
        .setContentTitle(id + ". email")
        .setGroup(GROUP_KEY)
        .setContentText("Content of " + id + ". email")
        .addAction(action).build();

    notificationManager.notify(id, newMessageNotification);
}

The important part here are the methods:

  • setGroupSummary(true) – Used for the first notification. This “summary” message won’t appear in the group and it will be the only notification on the devices with older Androids
  • setGroup(GROUP_KEY) – This is how you group the notifications together

Result

notifications

3. Styling notifications

Starting from Android N there are also new styling types available.

3.1 Styling conversations

MessagingStyle can be used for conversation-like notifications, like in the example below.

Example:

 
Notification notification = new Notification.Builder(this)
    .setContentTitle("Conversation with Dog")
    .setSmallIcon(android.R.drawable.ic_dialog_alert)
    .setColor(getColor(R.color.colorAccent))
    .setStyle(new Notification.MessagingStyle("Me")
        .setConversationTitle("Texting Dog")
        .addMessage("Hello?", new Date().getTime(), "Dog")
        .addMessage("Hello", new Date().getTime(), null)
        .addMessage("Yes, this is dog", new Date().getTime(), "Dog"))
    .build();
  • setColor(getColor(R.color.colorAccent)) – this method is available since Lollipop and it will color our notification
  • new Notification.MessagingStyle("Me") – text passed to the constructor will be colored and used in the message with null passed as a sender (it will appear as a sender of the notification)

Result

result_final

3.2 Styling remote views

DecoratedCustomViewStyle is most definitely another cool styling option. It helps in obtaining system decorations while using custom layouts with RemoteViews.

 
RemoteViews contentSmall = new RemoteViews(getPackageName(), R.layout.custom_notification_small);
RemoteViews contentBig = new RemoteViews(getPackageName(), R.layout.custom_notification_big);

contentSmall.setTextViewText(R.id.title, "Remote view title");
contentBig.setTextViewText(R.id.title, "Big remote view title");

Notification notification = new Notification.Builder(this)
    .setSmallIcon(android.R.drawable.ic_dialog_email)
    .setStyle(new Notification.DecoratedCustomViewStyle())
    .setCustomBigContentView(contentBig)
.build();

notificationManager.notify(notificationId, notification);

Example

result_final

See how bad it looks without Without DecoratedCustomViewStyle

result_final

All examples from this article are available on Github page NotificationsDemo

 

Written by Adrian Kremski
Android Developer
Published November 17, 2016