How to make a Facebook Messenger-like notification like this in Android
Categories:
Creating Facebook Messenger-like Notifications in Android

Learn how to implement rich, interactive notifications in Android that mimic the style and functionality of Facebook Messenger's chat heads and direct reply features.
Android notifications have evolved significantly, offering developers powerful tools to create engaging and informative user experiences. One of the most iconic and user-friendly notification styles is seen in apps like Facebook Messenger, featuring 'chat heads' (floating bubbles) and direct reply capabilities. This article will guide you through the process of implementing similar rich notifications in your Android application, focusing on key components like NotificationCompat.MessagingStyle
, PendingIntent
for actions, and handling replies.
Understanding Notification Channels and Styles
Before diving into the Messenger-like features, it's crucial to understand Android's notification system basics. Android 8.0 (API level 26) and higher introduced Notification Channels, which allow users to fine-tune notification settings for different categories of notifications from your app. For a chat application, you might have a 'New Messages' channel.
To achieve the Messenger-like appearance, we'll primarily use NotificationCompat.MessagingStyle
. This style is specifically designed for messaging apps and provides a rich layout for displaying conversations, including sender names, message content, and even avatars. It also lays the groundwork for inline replies.
flowchart TD A[App Initiates Notification] --> B{Android Version?} B -->|API 26+| C[Create Notification Channel] C --> D[Build Notification with MessagingStyle] B -->|API < 26| D D --> E[Add RemoteInput for Direct Reply] E --> F[Attach PendingIntent for Reply Action] F --> G[Display Notification] G --> H{User Interacts?} H -->|Taps Notification| I[Open Chat Activity] H -->|Uses Direct Reply| J[Send Reply via PendingIntent] J --> K[Update Notification (Optional)]
Flowchart of Android Notification Creation and Interaction
Implementing MessagingStyle and Direct Reply
The core of a Messenger-like notification lies in NotificationCompat.MessagingStyle
and RemoteInput
for direct replies. MessagingStyle
allows you to add multiple messages to a single notification, making it feel like a mini-conversation. RemoteInput
enables users to type a reply directly into the notification shade without opening the app.
Here's a breakdown of the steps involved:
- Create a Notification Channel (API 26+): Define a channel for your chat notifications.
- Build
MessagingStyle
: Add messages to the style, specifying sender and content. - Add
RemoteInput
: Create aRemoteInput
object to capture user input. - Create a
PendingIntent
for Reply: This intent will be triggered when the user sends a direct reply. - Attach Action to Notification: Combine the
RemoteInput
andPendingIntent
into aNotificationCompat.Action
and add it to your notification. - Display the Notification: Use
NotificationManagerCompat
to show the notification.
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.RemoteInput;
public class NotificationHelper {
public static final String CHANNEL_ID = "chat_channel";
public static final String KEY_TEXT_REPLY = "key_text_reply";
public static void createNotificationChannel(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Chat Notifications";
String description = "Notifications for new messages";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public static void showChatNotification(Context context, String sender, String message, int notificationId) {
createNotificationChannel(context);
// 1. Create a MessagingStyle
NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle("Me")
.setConversationTitle("Conversation with " + sender)
.addMessage(message, System.currentTimeMillis(), sender);
// 2. Create RemoteInput for direct reply
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
.setLabel("Reply...")
.build();
// 3. Create PendingIntent for reply action
Intent replyIntent = new Intent(context, ReplyReceiver.class);
replyIntent.putExtra("notificationId", notificationId);
replyIntent.putExtra("sender", sender);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(
context, notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// 4. Create NotificationCompat.Action
NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
android.R.drawable.ic_menu_send, "Reply", replyPendingIntent)
.addRemoteInput(remoteInput)
.build();
// 5. Build the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_email)
.setStyle(messagingStyle)
.addAction(replyAction)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
// 6. Display the notification
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(notificationId, builder.build());
}
}
NotificationHelper class for creating chat notifications with direct reply.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.core.app.RemoteInput;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.NotificationCompat;
public class ReplyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
CharSequence replyText = remoteInput.getCharSequence(NotificationHelper.KEY_TEXT_REPLY);
int notificationId = intent.getIntExtra("notificationId", 0);
String sender = intent.getStringExtra("sender");
// Process the reply (e.g., send to server, update UI)
System.out.println("Received reply for notification " + notificationId + " from " + sender + ": " + replyText);
// Optionally, update the notification to show the sent reply
// For a real app, you'd likely update the conversation in the MessagingStyle
// and re-notify with the same ID.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationHelper.CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_email)
.setContentTitle("Reply Sent")
.setContentText("You replied to " + sender + ": " + replyText)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true);
notificationManager.notify(notificationId, builder.build());
}
}
}
BroadcastReceiver to handle direct replies from the notification.
MessagingStyle
conversation, rather than creating a new 'Reply Sent' notification. This requires maintaining the MessagingStyle
state and re-notifying with the same notificationId
.Manifest Configuration and Usage
To ensure your ReplyReceiver
can handle the direct reply intents, you need to register it in your AndroidManifest.xml
.
To trigger the notification, you can call NotificationHelper.showChatNotification
from an Activity
, Service
, or BroadcastReceiver
when a new message arrives.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<application
...
<receiver android:name=".ReplyReceiver" android:exported="false"/>
...
</application>
</manifest>
Registering the ReplyReceiver in AndroidManifest.xml
// Example usage in an Activity or Service
public class MainActivity extends AppCompatActivity {
private int notificationCounter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_send_notification).setOnClickListener(v -> {
notificationCounter++;
NotificationHelper.showChatNotification(
this,
"Alice",
"Hey, how are you doing?",
notificationCounter
);
});
}
}
Example of triggering a chat notification.
FLAG_IMMUTABLE
flag for PendingIntent
is crucial for security on Android 12 (API 31) and above. If your app targets API 31+, you must specify either FLAG_IMMUTABLE
or FLAG_MUTABLE
when creating PendingIntent
objects.