Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีจัดกลุ่ม Notification แบบ WhatsApp ใน Android

ภาพรวม

การจัดกลุ่ม Notification (Notification Grouping) ให้ข้อความหลายข้อความจากคนเดียวกันหรือหัวข้อเดียวกันรวมเป็นกลุ่มเดียว คล้าย WhatsApp ทำได้โดยใช้ setGroup() และ setGroupSummary() ของ NotificationCompat

ตัวอย่าง: สร้าง Notification แบบจัดกลุ่ม

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → New Project → Empty Activity (Package: app.tutorialspoint.com.notifyme)

ขั้นตอนที่ 2: Layout (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="Create notification"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

ขั้นตอนที่ 3: MainActivity.java - สร้าง Notification กลุ่ม

package app.tutorialspoint.com.notifyme;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
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 -> createGroupedNotification());
    }

    private void createGroupedNotification() {
        messageCount++;
        String messageText = "Message #" + messageCount;

        // Notification ย่อย (Child) - แต่ละข้อความ
        NotificationCompat.Builder childBuilder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("New Message")
                .setContentText(messageText)
                .setStyle(new NotificationCompat.InboxStyle()
                        .addLine(messageText)
                        .setBigContentTitle("Messages from Chat")
                        .setSummaryText("+" + messageCount + " new messages"))
                .setGroup(GROUP_KEY_MESSAGES)
                .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN); // แจ้งเตียงแต่ละตัว

        // Notification สรุป (Summary/Parent) - แสดงเมื่อยุบกลุ่ม
        NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(this, DEFAULT_CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("Chat Messages")
                .setContentText(messageCount + " new messages")
                .setStyle(new NotificationCompat.InboxStyle()
                        .addLine("Latest: " + messageText)
                        .setBigContentTitle("Messages from Chat")
                        .setSummaryText(messageCount + " messages"))
                .setGroup(GROUP_KEY_MESSAGES)
                .setGroupSummary(true) // สำคัญ: บอกว่าเป็น Summary
                .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY); // แจ้งเตียงแค่ตัวสรุป

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

        // สร้าง Channel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    NOTIFICATION_CHANNEL_ID, 
                    "Message Notifications", 
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            channel.setDescription("Channel for grouped chat messages");
            manager.createNotificationChannel(channel);
            childBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            summaryBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        }

        // ส่ง Notification (ใช้ ID ต่างกัน)
        int childId = 1000 + messageCount;
        int summaryId = 999; // ID คงที่สำหรับ Summary
        
        manager.notify(childId, childBuilder.build());
        manager.notify(summaryId, summaryBuilder.build());
    }
}

ขั้นตอนที่ 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>

คีย์สำคัญของการจัดกลุ่ม

เมธอด/ค่าคงที่หน้าที่
setGroup(String groupKey)กำหนด Group Key ให้ Notification อยู่ในกลุ่มเดียวกัน
setGroupSummary(true)ระบุว่า Notification นี้คือ "ตัวสรุป" ของกลุ่ม
setGroupAlertBehavior()ควบคุมการแจ้งเตือน: GROUP_ALERT_ALL, GROUP_ALERT_CHILDREN, GROUP_ALERT_SUMMARY

Group Alert Behavior

  • GROUP_ALERT_ALL: แจ้งเตือนทุกตัวในกลุ่ม (เสียง/การสั่น ทุกครั้ง)
  • GROUP_ALERT_CHILDREN: แจ้งเตือนเฉพาะ Notification ย่อย (Summary ไม่แจ้ง)
  • GROUP_ALERT_SUMMARY: แจ้งเตือนเฉพาะ Summary (Child ไม่แจ้ง) - เหมาะสำหรับแชท

การจัดการ ID

  • Child Notification: ใช้ ID ต่างกันทุกครั้ง (เพื่อให้เพิ่มขึ้นเรื่อยๆ)
  • Summary Notification: ใช้ ID คงที่ (เพื่ออัปเดตตัวเดียวกัน)

การทดสอบ

  1. รันแอป กดปุ่ม "Create notification" หลายครั้ง
  2. ดู Notification Shade จะเห็นกลุ่มรวมเป็นหนึ่งรายการ
  3. ลากลงเพื่อขยาย จะเห็นรายการย่อยแต่ละข้อความ
  4. ลากขึ้นเพื่อยุบ จะเหลือแต่ Summary

ข้อควรพิจารณาเพิ่มเติม

  • ใช้ setSortKey() เพื่อควบคุมลำดับในกลุ่ม
  • สำหรับแอปแชทจริง ควรใช้ Firebase Cloud Messaging (FCM) ส่ง Push Notification จาก Server
  • Android 12+ (API 31) รองรับ Notification.Grouping ดีกว่า รวมถึง UI ใหม่
  • ควรจัดการการลบ Notification เมื่อผู้ใช้อ่านข้อความแล้ว (cancel by ID)
หมายเหตุ: กลุ่ม Notification ทำงานได้ดีที่สุดเมื่อแอปอยู่ใน Foreground หรือ Background ไม่ได้ถูก Kill หาก Process ถูก Kill จะต้องใช้ FCM Data Message เพื่อสร้าง Notification ใหม่