How to make a Facebook Messenger-like notification like this in Android

Learn how to make a facebook messenger-like notification like this in android with practical examples, diagrams, and best practices. Covers android development techniques with visual explanations.

Creating Facebook Messenger-like Notifications in Android

Hero image for How to make a Facebook Messenger-like notification like this 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:

  1. Create a Notification Channel (API 26+): Define a channel for your chat notifications.
  2. Build MessagingStyle: Add messages to the style, specifying sender and content.
  3. Add RemoteInput: Create a RemoteInput object to capture user input.
  4. Create a PendingIntent for Reply: This intent will be triggered when the user sends a direct reply.
  5. Attach Action to Notification: Combine the RemoteInput and PendingIntent into a NotificationCompat.Action and add it to your notification.
  6. 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.

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.