ภาพรวม
บทช่วยสอนนี้รวมคุณสมบัติ Notification ขั้นสูงไว้ด้วยกัน: การสั่น (Vibration), เสียง (Sound), Action Buttons, และ Big View Styles (BigText, BigPicture, Inbox, Messaging) เพื่อสร้าง Notification ที่โต้ตอบและสวยงาม
ตัวอย่างโค้ดครบถ้วน (Java)
ขั้นตอนที่ 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
package app.tutorialspoint.com.notifyme;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
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 {
private static final String DEFAULT_CHANNEL_ID = "default_channel";
private static final String CHANNEL_ID = "advanced_notifications";
private int notificationCounter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createNotificationChannel();
Button btnCreateNotification = findViewById(R.id.btnCreateNotification);
btnCreateNotification.setOnClickListener(v -> createAdvancedNotification());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"Advanced Notifications",
NotificationManager.IMPORTANCE_HIGH
);
channel.setDescription("Notifications with actions, big views, vibration & sound");
channel.enableVibration(true);
channel.setVibrationPattern(new long[]{0, 200, 100, 200, 100, 200});
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}
private void createAdvancedNotification() {
notificationCounter++;
// 1. Intent และ PendingIntent สำหรับ Content Tap
Intent mainIntent = new Intent(this, MainActivity.class);
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentPendingIntent = PendingIntent.getActivity(
this, 0, mainIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// 2. Action Buttons (สูงสุด 3 ปุ่ม)
// Action 1: Reply (ต้องใช้ RemoteInput สำหรับ Direct Reply)
Intent replyIntent = new Intent(this, NotificationActionReceiver.class)
.setAction("ACTION_REPLY")
.putExtra("notification_id", notificationCounter);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(
this, 1, replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// Action 2: Mark as Read
Intent readIntent = new Intent(this, NotificationActionReceiver.class)
.setAction("ACTION_MARK_READ")
.putExtra("notification_id", notificationCounter);
PendingIntent readPendingIntent = PendingIntent.getBroadcast(
this, 2, readIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// Action 3: Open App
Intent openIntent = new Intent(this, MainActivity.class);
openIntent.setAction("ACTION_OPEN");
PendingIntent openPendingIntent = PendingIntent.getActivity(
this, 3, openIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
// 3. สร้าง Notification พร้อม BigTextStyle
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Advanced Notification #" + notificationCounter)
.setContentText("This notification has Actions, BigText, Vibration & Sound")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText("Big View Styles: ข้อความยาวที่จะแสดงเต็มเมื่อผู้ใช้ขยาย Notification นี้ " +
"สามารถใส่ข้อความหลายบรรทัดได้ และรองรับการ format แบบง่ายๆ"))
.setContentIntent(contentPendingIntent)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[]{0, 200, 100, 200, 100, 200}) // Fallback สำหรับ API < 26
.setDefaults(NotificationCompat.DEFAULT_SOUND) // ใช้เสียง Default
// เพิ่ม Action Buttons
.addAction(R.drawable.ic_launcher_foreground, "Reply", replyPendingIntent)
.addAction(R.drawable.ic_launcher_foreground, "Mark Read", readPendingIntent)
.addAction(R.drawable.ic_launcher_foreground, "Open App", openPendingIntent)
// Big Picture Style (ถ้ามีรูป)
// .setStyle(new NotificationCompat.BigPictureStyle()
// .bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.your_image))
// .setSummaryText("Image caption"))
// Inbox Style (สำหรับรายการ)
// .setStyle(new NotificationCompat.InboxStyle()
// .addLine("Item 1")
// .addLine("Item 2")
// .setBigContentTitle("3 new messages")
// .setSummaryText("Tap to view all"));
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(notificationCounter, builder.build());
}
}
ขั้นตอนที่ 4: BroadcastReceiver สำหรับ Action Buttons
สร้าง Class ใหม่: NotificationActionReceiver.java
package app.tutorialspoint.com.notifyme;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class NotificationActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
int notificationId = intent.getIntExtra("notification_id", -1);
if ("ACTION_REPLY".equals(action)) {
// สำหรับ Direct Reply ต้องใช้ RemoteInput (ดูด้านล่าง)
Toast.makeText(context, "Reply clicked for #" + notificationId, Toast.LENGTH_SHORT).show();
Log.d("NotificationAction", "Reply action");
} else if ("ACTION_MARK_READ".equals(action)) {
Toast.makeText(context, "Marked as read #" + notificationId, Toast.LENGTH_SHORT).show();
Log.d("NotificationAction", "Mark read action");
// TODO: อัปเดต Database, ลบ Notification, etc.
} else if ("ACTION_OPEN".equals(action)) {
Log.d("NotificationAction", "Open action");
}
}
}
ขั้นตอนที่ 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">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android 13+ -->
<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>
<receiver android:name=".NotificationActionReceiver" android:exported="false">
<intent-filter>
<action android:name="ACTION_REPLY" />
<action android:name="ACTION_MARK_READ" />
<action android:name="ACTION_OPEN" />
</intent-filter>
</receiver>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
Big View Styles เลือกใช้ตามเนื้อหา
| Style | ใช้เมื่อไหร่ | เมธอดสำคัญ | |---|---|---| | **BigTextStyle** | ข้อความยาว, บทความ, รายละเอียด |bigText(String), setBigContentTitle(), setSummaryText() |
| **BigPictureStyle** | รูปภาพ, สติ๊กเกอร์, Media | bigPicture(Bitmap), bigLargeIcon(Bitmap), setSummaryText() |
| **InboxStyle** | รายการข้อความ, Email, List | addLine(String), setBigContentTitle(), setSummaryText() |
| **MessagingStyle** | แชท, SMS, Conversation | addMessage(Message), setConversationTitle(), setGroupConversation() |
ตัวอย่าง MessagingStyle (แชท)
NotificationCompat.MessagingStyle messagingStyle =
new NotificationCompat.MessagingStyle("Me")
.setConversationTitle("Group Chat")
.addMessage("Hello!", System.currentTimeMillis(), "John")
.addMessage("Hi there!", System.currentTimeMillis(), "Jane")
.addMessage("How are you?", System.currentTimeMillis(), "John");
builder.setStyle(messagingStyle);
Direct Reply (ตอบกลับจาก Notification โดยตรง) - API 24+
// ใน Builder
RemoteInput remoteInput = new RemoteInput.Builder("key_text_reply")
.setLabel("Reply...")
.build();
NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
R.drawable.ic_reply, "Reply", replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.build();
builder.addAction(replyAction);
ใน BroadcastReceiver/Service รับค่าด้วย:
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
CharSequence replyText = remoteInput.getCharSequence("key_text_reply");
// ประมวลผล replyText
}
การทดสอบ
- รันแอป กดปุ่ม Create Notification
- ดู Notification: มี Action Buttons 3 ปุ่ม, ขยายดู BigText
- กด Action Buttons → Toast แสดง Action ที่กด
- กดเนื้อหา Notification → เปิด MainActivity
- ลองตั้งค่าโหมดเงียบ (Do Not Disturb) → Notification HIGH จะยังแจ้งเตือนได้ (ถ้าอนุญาต)
หมายเหตุ: Android 13+ (API 33) ต้องขอ Permission POST_NOTIFICATIONS จากผู้ใช้ก่อนแสดง Notification