ภาพรวม
บทความนี้ซ้ำกับ ID 1004061556 และ 1004061557 สาธิตการใช้ AlarmManager + BroadcastReceiver สำหรับ Scheduled Notification
สรุปโค้ดหลัก (ไม่ซ้ำซ้อน)
MainActivity.java - การจัดตาราง
public class MainActivity extends AppCompatActivity {
public static final String CHANNEL_ID = "scheduled_channel";
private static final String DEFAULT_CHANNEL = "default";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, "Scheduled Notifications", NotificationManager.IMPORTANCE_HIGH);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}
// เรียกจาก Menu หรือปุ่ม
private void scheduleNotification(String title, String text, long delayMillis) {
Notification notification = new NotificationCompat.Builder(this, DEFAULT_CHANNEL)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setAutoCancel(true)
.setChannelId(CHANNEL_ID)
.build();
Intent intent = new Intent(this, NotificationPublisher.class);
intent.putExtra(NotificationPublisher.EXTRA_NOTIFICATION, notification);
intent.putExtra(NotificationPublisher.EXTRA_ID, (int) System.currentTimeMillis());
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long trigger = SystemClock.elapsedRealtime() + delayMillis;
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, trigger, pendingIntent);
}
}
NotificationPublisher.java (BroadcastReceiver)
public class NotificationPublisher extends BroadcastReceiver {
public static final String EXTRA_NOTIFICATION = "notification";
public static final String EXTRA_ID = "notification_id";
@Override
public void onReceive(Context context, Intent intent) {
Notification notification = intent.getParcelableExtra(EXTRA_NOTIFICATION);
int id = intent.getIntExtra(EXTRA_ID, 0);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Ensure channel exists
NotificationChannel channel = new NotificationChannel(
MainActivity.CHANNEL_ID, "Scheduled", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
manager.notify(id, notification);
}
}
AndroidManifest.xml
<manifest ...>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application ...>
<receiver android:name=".NotificationPublisher" android:exported="false" />
</application>
</manifest>
ข้อแตกต่างจากบทความก่อนหน้า
- ใช้
setExact()แทนset()เพื่อความแม่นยำเวลา (API 19+) - แยก Channel ID สำหรับ Scheduled Notification
- สร้าง Channel ล่วงหน้าใน onCreate()
- ใช้ Parcelable สำหรับ Notification object
เมื่อไหร่ควรใช้วิธีไหน?
- AlarmManager + BroadcastReceiver: การแจ้งเตือนที่ต้องการเวลาที่แม่นยำ (นาฬิกาปลุก, ยา)
- WorkManager: งานพื้นหลังทั่วไป, Sync ข้อมูล, Backup (น่าเชื่อถือกว่า)
- FCM (Firebase Cloud Messaging): Push Notification จากเซิร์ฟเวอร์