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

สร้างและจัดการ Notification Channels ใน Android

ภาพรวม

ตั้งแต่ Android 8.0 (Oreo, API 26) ทุก Notification ต้องผ่าน Notification Channel ช่องทางนี้ช่วยให้ผู้ใช้ควบคุมการแจ้งเตือนได้ละเอียด (เปิด/ปิดเสียง, การสั่น, แสดงบน Lockscreen, ระดับความสำคัญ) แอปสามารถสร้าง Channel หลายช่องสำหรับประเภท Notification ที่ต่างกัน

ตัวอย่าง: สร้าง Channel พร้อมการตั้งค่าครบถ้วน

ขั้นตอนที่ 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: เพิ่มไฟล์เสียง (res/raw/quite_impressed.mp3)

ขั้นตอนที่ 4: MainActivity.java - สร้าง Channel และ Notification

package app.tutorialspoint.com.notifyme;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.net.Uri;
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 CHANNEL_ID_HIGH = "channel_high_priority";
    public static final String CHANNEL_ID_LOW = "channel_low_priority";
    private static final String DEFAULT_CHANNEL_ID = "default";

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

        // สร้าง Channel ตอนเริ่มแอป (แนะนำ)
        createNotificationChannels();

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

    // สร้าง Channel หลายตัวสำหรับประเภทต่างๆ
    private void createNotificationChannels() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;

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

        // Channel 1: สำคัญสูง (Chat, Alert) - มีเสียง สั่น แสดงหัวข้อ
        NotificationChannel highChannel = new NotificationChannel(
                CHANNEL_ID_HIGH,
                "Urgent Notifications",
                NotificationManager.IMPORTANCE_HIGH
        );
        highChannel.setDescription("Important alerts, messages, calls");
        highChannel.enableLights(true);
        highChannel.setLightColor(Color.RED);
        highChannel.enableVibration(true);
        highChannel.setVibrationPattern(new long[]{0, 500, 200, 500});
        highChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        highChannel.setShowBadge(true);
        
        // Channel 2: สำคัญต่ำ (Promo, Info) - ไม่มีเสียง แสดงใน Shade อย่างเดียว
        NotificationChannel lowChannel = new NotificationChannel(
                CHANNEL_ID_LOW,
                "Promotions & Info",
                NotificationManager.IMPORTANCE_LOW
        );
        lowChannel.setDescription("Non-urgent updates, promotions");
        lowChannel.enableLights(false);
        lowChannel.enableVibration(false);
        lowChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
        lowChannel.setShowBadge(false);

        manager.createNotificationChannel(highChannel);
        manager.createNotificationChannel(lowChannel);
    }

    private void showNotificationWithHighPriorityChannel() {
        Uri soundUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + 
                getPackageName() + "/raw/quite_impressed.mp3");

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID_HIGH)
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setContentTitle("High Priority Alert")
                .setContentText("This uses the High Priority channel with custom sound")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setAutoCancel(true);

        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        
        // สำหรับ Android 8.0+ Channel จะถูกสร้างแล้วใน createNotificationChannels()
        // แต่ถ้ายังไม่สร้าง ให้สร้างที่นี่ก็ได้ (Idempotent)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // อัปเดตเสียงของ Channel (ถ้าต้องการเปลี่ยน) - ต้องสร้าง Channel ใหม่ ID ใหม่
            // channel.setSound(soundUri, audioAttributes); // ไม่ทำงานหลังสร้างแล้ว
        }

        int id = (int) System.currentTimeMillis();
        manager.notify(id, builder.build());
    }
}

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

Notification Channel - รายละเอียดสำคัญ

Importance Levels (ระดับความสำคัญ)

ค่าคงที่ระดับพฤติกรรม
IMPORTANCE_MAXด่วนที่สุดแสดงหัวข้อ (Heads-up), เสียง, สั่น, เหนือ Lockscreen
IMPORTANCE_HIGHสูงแสดงหัวข้อ, เสียง, สั่น
IMPORTANCE_DEFAULTปกติเสียง, สั่น, ไม่แสดงหัวข้อ
IMPORTANCE_LOWต่ำไม่มีเสียง, ไม่สั่น, แสดงใน Shade เท่านั้น
IMPORTANCE_MINน้อยที่สุดไม่มีเสียง, ไม่สั่น, ไม่แสดงใน Shade (เฉพาะ Badge)
IMPORTANCE_NONEไม่แจ้งเตือนไม่มีการแจ้งเตือนเลย เฉพาะ Badge

การตั้งค่าที่ Channel รองรับ

  • Sound: setSound(uri, audioAttributes) - ตั้งได้ครั้งเดียวตอนสร้าง
  • Vibration: enableVibration(true), setVibrationPattern(long[])
  • Light: enableLights(true), setLightColor(Color)
  • Lockscreen: setLockscreenVisibility(VISIBILITY_PUBLIC/PRIVATE/SECRET)
  • Badge: setShowBadge(true/false) - แสดงตัวเลขบน Icon Launcher
  • Bypass DND: setBypassDnd(true) - แจ้งเตือนแม้โหมดอย่ารบกวน (ต้องได้อนุญาตจาก User)

การจัดการ Channel แบบไดนามิก

1. อัปเดต Channel (จำกัด)

// สามารถอัปเดตได้: Name, Description, Importance (บางกรณี)
// ไม่สามารถอัปเดตได้: Sound, Vibration Pattern, Light, Lockscreen Visibility
// วิธีแก้: สร้าง Channel ใหม่ ID ใหม่ แล้วย้าย Notification ไปใช้ Channel ใหม่

2. ลบ Channel

manager.deleteNotificationChannel(CHANNEL_ID_HIGH);

3. ดึงข้อมูล Channel

NotificationChannel channel = manager.getNotificationChannel(CHANNEL_ID_HIGH);
if (channel != null) {
    int importance = channel.getImportance();
    boolean vibrationEnabled = channel.shouldVibrate();
    // ...
}

4. กลุ่ม Channel (Channel Groups) - API 26+

// สร้าง Group
NotificationChannelGroup group = new NotificationChannelGroup("group_id", "Chat Notifications");
manager.createNotificationChannelGroup(group);

// กำหนด Channel ให้อยู่ใน Group
channel.setGroup("group_id");

แนวทางปฏิบัติที่ดี

  1. สร้าง Channel ตอนเริ่มแอป (Application.onCreate() หรือ Activity แรก) ไม่ใช่ตอนส่ง Notification
  2. จัดกลุ่ม Channel ตามประเภท: Chat, Promo, System, Update, dll.
  3. ตั้งชื่อ Channel ให้ผู้ใช้เข้าใจ: "Direct Messages", "Promotions", "Security Alerts"
  4. ใช้ Importance ให้เหมาะสม: อย่าใช้ HIGH สำหรับ Promo
  5. ทดสอบบนอุปกรณ์จริง เพราะ UI Settings ต่างกันตาม廠商 (Samsung, Xiaomi, Pixel)

การทดสอบ

  1. รันแอป กดปุ่มสร้าง Notification
  2. ไป Settings → Apps → [Your App] → Notifications
  3. จะเห็น 2 Channel: "Urgent Notifications" และ "Promotions & Info"
  4. ลองปิดเสียง Channel "Promotions" → สร้าง Notification ใหม่ด้วย Channel นั้น → จะไม่มีเสียง
สำคัญ: การจัดการ Channel ถูกต้องส่งผลต่อ UX และ App Store Rating โดยตรง ผู้ใช้รบกวนได้ง่ายหากแจ้งเตือนมากเกินไปหรือไม่เกี่ยวข้อง