In this tutorial, we’ll be discussing the changes introduced in the Notification System and its UI with Android P. We’ll be demonstrating it with a simple Android Application.
Android P Notifications
Android Pie has introduced a new Messaging Style Notification UI which provides simplified conversations.
Moreover, we can now display images with text in the messaging style as well.
With Android P, the addMessage()
function of the MessagingStyle Class has changed. Now instead of passing the String, we pass the Person
object which ties that notification and its message to that person.
setData
is used to display the image on the message.
setSemanticAction
is used to set predefined references to notification actions.
Following are the semantic actions available:
- SEMANTIC_ACTION_NONE
- SEMANTIC_ACTION_REPLY
- SEMANTIC_ACTION_MARK_AS_READ
- SEMANTIC_ACTION_MARK_AS_UNREAD
- SEMANTIC_ACTION_DELETE
- SEMANTIC_ACTION_ARCHIVE
- SEMANTIC_ACTION_MUTE
- SEMANTIC_ACTION_UNMUTE
- SEMANTIC_ACTION_THUMBS_UP
- SEMANTIC_ACTION_THUMBS_DOWN
- SEMANTIC_ACTION_CALL
setGroupConversation
is used to identify a notification group as a conversation.
In the next section, we’ll implement the different types of Notifications in Android P.
Simple Message Notifications
1 2 3 4 5 6 7 8 9 10 11 12 |
private void simpleNotification() { Person jd = new Person.Builder() .setName("JournalDev") .setImportant(true) .build(); new NotificationCompat.MessagingStyle(jd) .addMessage("Check me out", new Date().getTime(), jd) .setBuilder(builder); notificationManager.notify(1, builder.build()); } |
Inside the addMessage
, we pass the message, time(long), and the Person object.
setImportant
true indicates that the message would be displayed at the top in the conversation if the notification is collapsed.
Message Notification With Icon
By default, the icon displayed is the first letter of the Person.
We can set a custom icon in place as shown below:
1 2 3 4 5 6 7 8 9 10 11 |
Person anupam = new Person.Builder() .setName("Anupam") .setIcon(IconCompat.createWithResource(this, R.drawable.sample_photo)) .setImportant(true) .build(); new NotificationCompat.MessagingStyle(anupam) .addMessage("Check out my latest article!", new Date().getTime(), anupam) .setBuilder(builder); notificationManager.notify(2, builder.build()); |
Notification With Image
We can set the image type and uri in the setData
method as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void notificationWithImage() { Person bot = new Person.Builder() .setName("Bot") .setImportant(true) .setBot(true) .build(); Uri uri = Uri.parse("android.resource://com.journaldev.androidpnotifications/drawable/"+R.drawable.sample_bg); NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("Check out my latest article!", new Date().getTime(), bot); message.setData("image/*",uri); new NotificationCompat.MessagingStyle(bot) .addMessage(message) .setGroupConversation(true) .setBuilder(builder); notificationManager.notify(3, builder.build()); } |
setBot
to true indicates that the Person type is a machine.
Message Conversation Notification
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
private void notificationWithGroupConvo() { Person jd = new Person.Builder() .setName("JournalDev") .build(); Person anupam = new Person.Builder() .setName("Anupam") .setIcon(IconCompat.createWithResource(this, R.drawable.sample_photo)) .setImportant(true) .build(); Person bot = new Person.Builder() .setName("Bot") .setBot(true) .build(); Uri uri = Uri.parse("android.resource://com.journaldev.androidpnotifications/drawable/"+R.drawable.sample_bg); NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("", new Date().getTime(), bot); message.setData("image/*",uri); new NotificationCompat.MessagingStyle(bot) .addMessage("Hi. How are you?", new Date().getTime(), anupam) .addMessage(message) .addMessage("Does this image look good?", new Date().getTime(), bot) .addMessage("Looks good!", new Date().getTime(), jd) .setGroupConversation(true) .setConversationTitle("Sample Conversation") .setBuilder(builder); notificationManager.notify(4, builder.build()); } |
The messages are displayed in the order in which the addMessage
methods are set.
In the following section, we’ll aggregate the above-learned concepts along with semantic actions.
We’ll be using the AndroidX Packaging System.
Project Structure
Android P Notification Project
Code
The code for the activity_main.xml
layout is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" tools:context=".MainActivity"> <Button android:id="@+id/btnSimpleNotification" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Simple Notification" /> <Button android:id="@+id/btnNotificationIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notification With Icon" /> <Button android:id="@+id/btnNotificationImage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notification With Image" /> <Button android:id="@+id/btnNotificationWithGroupConvo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notification With Group Conversation" /> <Button android:id="@+id/btnNotificationSemantic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notification Semantic Action" /> </LinearLayout> |
The code for the MainActivity.java class is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
package com.journaldev.androidpnotifications; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; import androidx.core.app.NotificationCompat; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.Person; import androidx.core.graphics.drawable.IconCompat; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; import java.util.Date; public class MainActivity extends AppCompatActivity implements View.OnClickListener { NotificationManager notificationManager; NotificationCompat.Builder builder; NotificationChannel channel; CharSequence charSequence = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnSimpleNotification = findViewById(R.id.btnSimpleNotification); Button btnNotificationIcon = findViewById(R.id.btnNotificationIcon); Button btnNotificationImage = findViewById(R.id.btnNotificationImage); Button btnNotificationWithGroupConvo = findViewById(R.id.btnNotificationWithGroupConvo); Button btnNotificationSemantic = findViewById(R.id.btnNotificationSemantic); charSequence = btnNotificationIcon.getText(); btnSimpleNotification.setOnClickListener(this); btnNotificationIcon.setOnClickListener(this); btnNotificationImage.setOnClickListener(this); btnNotificationWithGroupConvo.setOnClickListener(this); btnNotificationSemantic.setOnClickListener(this); notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); CharSequence name = "My Notification"; String description = "yadda yadda"; int importance = NotificationManager.IMPORTANCE_DEFAULT; channel = new NotificationChannel("1", name, importance); channel.setDescription(description); builder = new NotificationCompat.Builder(MainActivity.this, channel.getId()) .setSmallIcon(R.mipmap.ic_launcher); notificationManager.createNotificationChannel(channel); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnSimpleNotification: simpleNotification(); break; case R.id.btnNotificationIcon: notificationWithIcon(); break; case R.id.btnNotificationImage: notificationWithImage(); break; case R.id.btnNotificationWithGroupConvo: notificationWithGroupConvo(); break; case R.id.btnNotificationSemantic: notificationSemantic(); break; } } private void simpleNotification() { Person jd = new Person.Builder() .setName("JournalDev") .setImportant(true) .build(); new NotificationCompat.MessagingStyle(jd) .addMessage("Check me out", new Date().getTime(), jd) .setBuilder(builder); notificationManager.notify(1, builder.build()); } private void notificationWithIcon() { Person anupam = new Person.Builder() .setName("Anupam") .setIcon(IconCompat.createWithResource(this, R.drawable.sample_photo)) .setImportant(true) .build(); new NotificationCompat.MessagingStyle(anupam) .addMessage("Check out my latest article!", new Date().getTime(), anupam) .setBuilder(builder); notificationManager.notify(2, builder.build()); } private void notificationWithImage() { Person bot = new Person.Builder() .setName("Bot") .setImportant(true) .setBot(true) .build(); Uri uri = Uri.parse("android.resource://com.journaldev.androidpnotifications/drawable/"+R.drawable.sample_bg); NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("Check out my latest article!", new Date().getTime(), bot); message.setData("image/*",uri); new NotificationCompat.MessagingStyle(bot) .addMessage(message) .setGroupConversation(true) .setBuilder(builder); notificationManager.notify(3, builder.build()); } private void notificationWithGroupConvo() { Person jd = new Person.Builder() .setName("JournalDev") .build(); Person anupam = new Person.Builder() .setName("Anupam") .setIcon(IconCompat.createWithResource(this, R.drawable.sample_photo)) .setImportant(true) .build(); Person bot = new Person.Builder() .setName("Bot") .setBot(true) .build(); Uri uri = Uri.parse("android.resource://com.journaldev.androidpnotifications/drawable/"+R.drawable.sample_bg); NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("", new Date().getTime(), bot); message.setData("image/*",uri); new NotificationCompat.MessagingStyle(bot) .addMessage("Hi. How are you?", new Date().getTime(), anupam) .addMessage(message) .addMessage("Does this image look good?", new Date().getTime(), bot) .addMessage("Looks good!", new Date().getTime(), jd) .setGroupConversation(true) .setConversationTitle("Sample Conversation") .setBuilder(builder); notificationManager.notify(4, builder.build()); } private void notificationSemantic() { Person jd = new Person.Builder() .setName("JournalDev") .build(); Person anupam = new Person.Builder() .setName("Anupam") .setIcon(IconCompat.createWithResource(this, R.drawable.sample_photo)) .setImportant(true) .build(); Person bot = new Person.Builder() .setName("Bot") .setBot(true) .build(); Uri uri = Uri.parse("android.resource://com.journaldev.androidpnotifications/drawable/"+R.drawable.sample_bg); Intent intent = new Intent(this, MainActivity.class); intent.putExtra("hi","Notifications were read"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("", new Date().getTime(), bot); message.setData("image/*",uri); NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder( R.drawable.sample_bg, "MARK READ", pendingIntent) .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) .build(); NotificationCompat.Builder separateBuilder = builder; separateBuilder.addAction(replyAction); new NotificationCompat.MessagingStyle(bot) .addMessage("Hi. How are you?", new Date().getTime(), anupam) .addMessage(message) .addMessage("Does this image look good?", new Date().getTime(), bot) .addMessage("Looks good!", new Date().getTime(), jd) .setGroupConversation(true) .setConversationTitle("Sample Conversation") .setBuilder(separateBuilder); notificationManager.notify(5, separateBuilder.build()); } @Override protected void onResume() { super.onResume(); if(getIntent()!=null && getIntent().getExtras()!=null) { String value = getIntent().getStringExtra("hi"); Toast.makeText(getApplicationContext(),value,Toast.LENGTH_LONG).show(); } } } |
When the semantic action button is clicked, we show the intent data in a Toast.
The output of the above application in action is given below:
Android P Notification Output
That brings an end to this tutorial. You can download the project from the link below or view the full source code in our Github Repository below.