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
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:
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:
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
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:
<?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:
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.