Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Nhóm thông báo Android kiểu WhatsApp với InboxStyle

Để gom nhiều thông báo thành một nhóm (group) như WhatsApp, Messenger, sử dụng NotificationCompat.InboxStyle kết hợp với setGroup() và setGroupSummary().

Các bước thực hiện

Bước 1: Tạo dự án mới

Tạo dự án Android Studio, package app.tutorialspoint.com.notifyme.

Bước 2: Giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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:padding="16dp"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnCreateNotification"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Tạo thông báo nhóm"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Bước 3: Tạo notification nhóm (src/MainActivity.java)

package app.tutorialspoint.com.notifyme;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import androidx.core.app.NotificationCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    public static final String NOTIFICATION_CHANNEL_ID = "10001";
    private static final String DEFAULT_CHANNEL_ID = "default";
    private static final String GROUP_KEY_MESSAGES = "group_key_messages";
    private int messageCount = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnCreateNotification = findViewById(R.id.btnCreateNotification);
        btnCreateNotification.setOnClickListener(v -> createGroupNotification());
    }

    private void createGroupNotification() {
        messageCount++;

        // Tạo notification con (child)
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("Tin nhắn mới " + messageCount)
            .setContentText("Nội dung tin nhắn thứ " + messageCount)
            .setStyle(new NotificationCompat.InboxStyle()
                .addLine("Người gửi A: Tin nhắn 1")
                .addLine("Người gửi B: Tin nhắn 2")
                .addLine("Người gửi C: Tin nhắn 3")
                .setBigContentTitle(messageCount + " tin nhắn mới")
                .setSummaryText("Nhấn để xem chi tiết"))
            .setGroup(GROUP_KEY_MESSAGES) // Quan trọng: cùng group key
            .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); // Chỉ alert cho child mới

        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID, "Kênh tin nhắn", importance);
            manager.createNotificationChannel(channel);
            builder.setChannelId(NOTIFICATION_CHANNEL_ID);
        }

        // Notification con có ID riêng
        int childId = (int) System.currentTimeMillis();
        manager.notify(GROUP_KEY_MESSAGES.hashCode(), childId, builder.build());

        // Cập nhật summary (notification cha) - hiển thị khi thu gọn
        updateGroupSummary(manager);
    }

    private void updateGroupSummary(NotificationManager manager) {
        NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("Tin nhắn")
            .setContentText(messageCount + " tin nhắn mới")
            .setStyle(new NotificationCompat.InboxStyle()
                .setBigContentTitle(messageCount + " tin nhắn mới")
                .setSummaryText("Nhấn để mở ứng dụng"))
            .setGroup(GROUP_KEY_MESSAGES)
            .setGroupSummary(true) // Đánh dấu là summary
            .setChannelId(NOTIFICATION_CHANNEL_ID);

        // Summary dùng ID cố định để cập nhật
        manager.notify(GROUP_KEY_MESSAGES.hashCode(), 9999, summaryBuilder.build());
    }
}

Bước 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.tutorialspoint.com.notifyme">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Giải thích cơ chế nhóm (Grouping)

  • setGroup(GROUP_KEY): Tất cả notification cùng GROUP_KEY sẽ được gom lại.
  • setGroupSummary(true): Chỉ một notification được đánh dấu là summary (cha). Nó hiển thị khi nhóm bị thu gọn.
  • InboxStyle: Hiển thị nhiều dòng văn bản trong expanded view, phù hợp cho danh sách tin nhắn.
  • GROUP_ALERT_CHILDREN: Chỉ notification con mới phát âm thanh/rung; summary không làm phiền.

Mẹo thực tế

  • Trong app chat thực tế, dùng RemoteInput cho phép trả lời ngay từ notification.
  • Lưu messageCount vào SharedPreferences hoặc database để khôi phục khi app restart.
  • Xử lý xóa notification con khi user đã đọc tin nhắn tương ứng.