AlarmManager: แนวคิดหลักและการทำงานกับการปลุก

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-28 เวลาอ่าน: 8 นาที

AlarmManager เป็นบริการระบบ Android ที่ช่วยให้แอปพลิเคชันทำงานตามเวลาที่กำหนดได้ แม้ว่าแอปพลิเคชันจะไม่ได้ทำงานอยู่หรืออุปกรณ์อยู่ในโหมดสลับก็ตาม แตกต่างจาก JobScheduler หรือ WorkManager ตรงที่ AlarmManager รับประกันความแม่นยำในการเรียกใช้ ทำให้เป็นสิ่งที่ขาดไม่ได้สำหรับการปลุก การเตือนในปฏิทิน และงานที่สำคัญต่อเวลาในการทำงาน ตาม Android Developers, 2026 ตั้งแต่ Android 4.4 เป็นต้นไป setRepeating จะทำงานเป็นการทำซ้ำที่ไม่แม่นยำ และการปลุกที่แม่นยำจำเป็นต้องใช้ setExact หรือ setAlarmClock

ประเด็นสำคัญ

  • AlarmManager เป็นบริการระบบ Android สำหรับทำงานตามเวลาที่แม่นยำ ทำงานแม้ในโหมดสลับ
  • ประเภทการปลุก ประกอบด้วย ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP และ RTC_WAKEUP — แบบปลุกและไม่ปลุก
  • setExact รับประกันการเรียกใช้ที่แม่นยำบน Android 4.4+ แต่ใช้พลังงานแบตเตอรี่มากกว่า
  • setAlarmClock เป็นวิธีเดียวที่ระบบรับประกันว่าจะทำงานตรงเวลาบน Android 6+
  • ตั้งแต่ Android 12 การปลุกที่แม่นยำจำเป็นต้องมีสิทธิ์ SCHEDULE_EXACT_ALARM

AlarmManager คืออะไร?

AlarmManager เป็นบริการระบบ Android ที่ให้ API สำหรับกำหนดเวลาทำงานด้วยเวลาที่แม่นยำหรือโดยประมาณ มีมาตั้งแต่ Android เวอร์ชันแรกและยังคงเป็นวิธีที่เชื่อถือได้เพียงวิธีเดียวในการเรียกใช้โค้ด ณ เวลาที่กำหนด โดยไม่ขึ้นกับสถานะของแอปพลิเคชันและอุปกรณ์

หลักการทำงานเรียบง่าย: แอปพลิเคชันส่ง PendingIntent ไปยังระบบพร้อมกับเวลาที่กำหนด เมื่อถึงเวลาที่กำหนด ระบบจะส่ง Intent ไปยัง BroadcastReceiver ที่ลงทะเบียนไว้หรือเริ่ม Service แม้ว่าอุปกรณ์จะอยู่ในโหมดสลับ WakeLock ก็ช่วยให้โปรเซสเซอร์ตื่นขึ้นและประมวลผลเหตุการณ์ได้

พื้นที่การใช้งานหลัก ของ AlarmManager คืองานที่ต้องการเวลาที่แม่นยำ: การปลุก การเตือนในปฏิทิน การเริ่มดำเนินการระยะยาวในเวลาที่กำหนด สำหรับงานที่ความแม่นยำไม่สำคัญ (การซิงค์รายวัน) Google แนะนำ WorkManager หรือ JobScheduler เนื่องจากประหยัดพลังงานมากกว่า

AlarmManager ทำงานอย่างไร?

AlarmManager รับ PendingIntent และเวลาเรียกใช้จากแอปพลิเคชัน ระบบบันทึกคำขอนี้ในตัวกำหนดเวลาภายในและปลุกโปรเซสเซอร์ตามเวลาที่กำหนดเพื่อส่ง Intent นักพัฒนาต้องลงทะเบียน BroadcastReceiver ล่วงหน้าเพื่อจัดการ Intent นี้

ประเภทการปลุก

AlarmManager รองรับการปลุก 4 ประเภท: ELAPSED_REALTIME (เวลาตั้งแต่บูต ไม่ปลุก), RTC (เวลาจริง ไม่ปลุก), ELAPSED_REALTIME_WAKEUP (เวลาตั้งแต่บูต ปลุกอุปกรณ์) และ RTC_WAKEUP (เวลาจริง ปลุก) เวอร์ชัน WAKEUP จำเป็นหากต้องทำงานแม้อุปกรณ์อยู่ในโหมดหลับ

ประเภทเวลาปลุกตัวอย่าง
ELAPSED_REALTIMEตั้งแต่บูตไม่ตัวจับเวลาใช้งาน
RTCการประทับเวลา Unixไม่การบันทึก
ELAPSED_REALTIME_WAKEUPตั้งแต่บูตใช่งานประจำ
RTC_WAKEUPการประทับเวลา Unixใช่นาฬิกาปลุก

สิทธิ์และอนุญาต

ตั้งแต่ Android 12 (API 31) การใช้การปลุกที่แม่นยำ (setExact) จำเป็นต้องมีสิทธิ์ SCHEDULE_EXACT_ALARM ผู้ใช้สามารถเพิกถอนได้ผ่านการตั้งค่า สำหรับแอปพลิเคชันที่ต้องการการปลุกที่แม่นยำพร้อมการแสดงผล (เช่น แอปนาฬิกา) จะใช้ USE_EXACT_ALARM ซึ่งให้มาตอนติดตั้ง

เมธอด set, setRepeating และ setExact

AlarmManager มีสามเมธอดหลักสำหรับกำหนดเวลาทำงาน การเลือกเมธอดจะกำหนดความแม่นยำในการเรียกใช้และผลกระทบต่อการใช้พลังงานของอุปกรณ์

set — เมธอดพื้นฐานสำหรับการเรียกใช้ครั้งเดียวที่ไม่แม่นยำ ระบบอาจเลื่อนเวลาได้ถึงสองสามนาทีเพื่อจัดกลุ่มกับเหตุการณ์อื่น เหมาะสำหรับงานที่ความแม่นยำไม่สำคัญ: การเตือนให้เปิดแอปพลิเคชัน

setRepeating — เมธอดสำหรับการทำซ้ำเป็นระยะ ตั้งแต่ Android 4.4 (API 19) setRepeating ไม่แม่นยำอีกต่อไป — ช่วงเวลาอาจแตกต่างกันไป ระบบไม่รับประกันช่วงเวลาคงที่อีกต่อไป แทนที่จะใช้ setRepeating แนะนำให้ใช้ setExact พร้อมกำหนดเวลาใหม่หรือ WorkManager พร้อม PeriodicWorkRequest

setExact — เมธอดสำหรับการเรียกใช้ครั้งเดียวที่แม่นยำ ระบบจะปลุกอุปกรณ์ให้ใกล้เคียงกับเวลาที่กำหนดมากที่สุด setAlarmClock เป็นกรณีพิเศษของ setExact ที่แสดงไอคอนปลุกในแถบสถานะและมีลำดับความสำคัญสูงสุดในบรรดาการปลุกทุกประเภท

kotlin
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

// การปลุกครั้งเดียวที่แม่นยำ
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    this, 0, intent,
    PendingIntent.FLAG_IMMUTABLE
)

alarmManager.setAlarmClock(
    AlarmManager.AlarmClockInfo(
        targetTime, pendingIntent
    ),
    pendingIntent
)

ตัวอย่างการใช้งาน AlarmManager

สถานการณ์ทั่วไป คือการสร้างการเตือนรายวันตามเวลาที่กำหนด โดยใช้ RTC_WAKEUP พร้อม setExact เพื่อจุดประสงค์นี้ เมื่อถูกเรียกใช้ BroadcastReceiver จะเริ่มการแจ้งเตือนหรือ Service หลังจากการประมวลผล ต้องกำหนดเวลางานใหม่สำหรับวันถัดไป

kotlin
class ReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        val notificationManager =
            context.getSystemService(Context.NOTIFICATION_SERVICE)
                as NotificationManager

        val notification = NotificationCompat.Builder(
            context, "reminder_channel"
        )
            .setContentTitle("การเตือน")
            .setContentText("ถึงเวลาทำงานให้เสร็จ")
            .setSmallIcon(R.drawable.ic_reminder)
            .build()

        notificationManager.notify(1001, notification)
    }
}

สำหรับการทำซ้ำรายวัน จะใช้ setExact พร้อมการคำนวณเวลาเรียกใช้ถัดไป สามารถส่งแฟล็กใน Intent เพื่อระบุประเภทการเตือนต่างๆ ตรวจสอบให้แน่ใจว่า BroadcastReceiver ลงทะเบียนใน AndroidManifest.xml พร้อมการจัดการการดำเนินการ WAKEUP

kotlin
fun scheduleDailyReminder(context: Context, hour: Int, minute: Int) {
    val calendar = Calendar.getInstance().apply {
        set(Calendar.HOUR_OF_DAY, hour)
        set(Calendar.MINUTE, minute)
        set(Calendar.SECOND, 0)
        if (before(Calendar.getInstance())) {
            add(Calendar.DAY_OF_MONTH, 1)
        }
    }

    val alarmManager =
        context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

    alarmManager.setExactAndAllowWhileIdle(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        pendingIntent
    )
}

การปรับแต่งและคำแนะนำ

AlarmManager เป็นเครื่องมือที่ทรงพลังแต่ใช้พลังงานมาก การปลุก WAKEUP แต่ละครั้งจะนำอุปกรณ์ออกจากโหมดสลับ ทำให้สิ้นเปลืองแบตเตอรี่ Google แนะนำให้ลดการใช้การปลุกที่แม่นยำและเลือกใช้ setExactAndAllowWhileIdle บน Android 6+ เพื่อลดผลกระทบต่อ Doze Mode สำหรับงานประจำที่ไม่ต้องการความแม่นยำ ให้ใช้ WorkManager พร้อม PeriodicWorkRequest ซึ่งไม่ต้องปลุกอุปกรณ์และไม่ทำให้แบตเตอรี่หมดในแต่ละครั้งที่ทำงาน

การทดสอบ AlarmManager ใน Unit Test

สำหรับการทดสอบ AlarmManager ให้ใช้ TestAlarmManager จาก Android Test Framework ซึ่งช่วยจำลองการเรียกใช้การปลุกโดยไม่ต้องรอเวลาจริง Robolectric มี ShadowAlarmManager ที่สกัดกั้นการเรียก set, setExact และ setRepeating โดยให้เมธอดสำหรับการบังคับเรียกใช้และการตรวจสอบจำนวนงานที่กำหนดไว้ สำหรับ Unit Test ของ BroadcastReceiver ให้ใช้ Robolectric.getForegroundScheduler() นอกจากนี้ยังมีการทดสอบ Espresso พร้อม IdlingResource ที่รอการเรียกใช้การปลุกในการทดสอบแบบบูรณาการ

การย้ายจาก AlarmManager ไปยัง WorkManager

หากแอปพลิเคชันของคุณใช้ AlarmManager สำหรับงานประจำที่ไม่ต้องการเวลาที่แม่นยำ ให้พิจารณาย้ายไปยัง WorkManager PeriodicWorkRequest ที่มีช่วงเวลาขั้นต่ำ 15 นาทีแทนที่ setRepeating ในขณะที่ WorkManager รับประกันการทำงานหลังรีบูต จัดการ Doze Mode และไม่ต้องการสิทธิ์ SCHEDULE_EXACT_ALARM สำหรับงานที่สำคัญต่อเวลา (ปลุกตอน 7 โมงเช้า) AlarmManager ยังคงเป็นตัวเลือกที่ถูกต้องเท่านั้น กลยุทธ์ที่ดีที่สุดคือใช้ AlarmManager เฉพาะการปลุกด้วย setAlarmClock และย้ายงานพื้นหลังอื่นๆ ทั้งหมดไปยัง WorkManager

สำหรับงานประจำที่ไม่ต้องการความแม่นยำ ให้ใช้ WorkManager พร้อม PeriodicWorkRequest สำหรับงานที่มีเวลาที่แม่นยำแต่ไม่สำคัญที่จะต้องเรียกใช้ในโหมดสลับ — ให้ใช้ setExact โดยไม่มี WAKEUP และเฉพาะการปลุกที่ต้องปลุกเท่านั้น — ให้ใช้ setAlarmClock หรือ RTC_WAKEUP

สิ่งสำคัญคือต้องตรวจสอบสิทธิ์ SCHEDULE_EXACT_ALARM บน Android 12+ หากไม่ได้รับสิทธิ์ setExact จะทำงานเหมือน set ทั่วไป (ไม่แม่นยำ) ใช้ AlarmManager.canScheduleExactAlarms() เพื่อตรวจสอบ หากไม่มีสิทธิ์ คุณสามารถแจ้งให้ผู้ใช้ไปที่การตั้งค่าผ่าน Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM)

การจัดการ BOOT_COMPLETED เพื่อกู้คืนการปลุก

คุณสมบัติที่สำคัญอย่างยิ่งของ AlarmManager — การปลุกที่กำหนดไว้ทั้งหมดจะถูกรีเซ็ตหลังจากรีสตาร์ทอุปกรณ์ เพื่อกู้คืนการปลุกเหล่านี้ คุณต้องประกาศ BroadcastReceiver ที่จัดการ Intent.ACTION_BOOT_COMPLETED และกำหนดเวลาการปลุกที่ใช้งานอยู่ทั้งหมดใหม่ในเมธอด onReceive หากไม่ดำเนินการนี้ ผู้ใช้จะสูญเสียการเตือนทั้งหมดหลังจากปิดและเปิดโทรศัพท์

kotlin
class BootReceiver : BroadcastReceiver() {
    override fun onReceive(
        context: Context,
        intent: Intent
    ) {
        if (intent.action ==
            Intent.ACTION_BOOT_COMPLETED
        ) {
            val prefs =
                context.getSharedPreferences("alarms", 0)
            val savedTime =
                prefs.getLong("next_alarm", 0L)
            if (savedTime > System.currentTimeMillis()) {
                scheduleReminder(context, savedTime)
            }
        }
    }
}

ในทางปฏิบัติ AlarmManager ยังคงเป็นโซลูชันที่ดีที่สุดสำหรับแอปพลิเคชันนาฬิกาปลุก ปฏิทิน การเตือนกินยา และงานใดๆ ที่เวลาในการทำงานมีความสำคัญต่อผู้ใช้ สำหรับสถานการณ์งานพื้นหลังอื่นๆ ทั้งหมด WorkManager หรือ JobScheduler เป็นที่นิยมกว่า

เมื่อเลือกระหว่าง AlarmManager และ WorkManager ให้ปฏิบัติตามกฎนี้: หากผู้ใช้ขอให้เตือนเวลาบ่าย 2:30 อย่างชัดเจน — ให้ใช้ AlarmManager พร้อม setAlarmClock หากงานควรทำงาน “ประมาณครั้งละหนึ่งชั่วโมง” — WorkManager พร้อม PeriodicWorkRequest จะประหยัดพลังงานและเชื่อถือได้มากกว่า

คำถามที่พบบ่อย

ความแตกต่างระหว่าง setExact และ setAlarmClock คืออะไร?

ทั้งสองเมธอดรับประกันการเรียกใช้ที่แม่นยำ แต่ setAlarmClock จะแสดงไอคอนปลุกในแถบสถานะเพิ่มเติมและแจ้งระบบว่าเป็นการปลุกของผู้ใช้ บน Android 6+ setAlarmClock มีภูมิคุ้มกันจาก Doze Mode ในขณะที่ setExact อาจล่าช้า

AlarmManager ทำงานอย่างไรหลังจากรีสตาร์ทอุปกรณ์?

หลังจากรีสตาร์ท การปลุกที่กำหนดไว้ทั้งหมดจะถูกรีเซ็ต เพื่อกู้คืนการปลุกเหล่านี้ คุณต้องลงทะเบียน BroadcastReceiver สำหรับการดำเนินการ BOOT_COMPLETED และกำหนดเวลางานทั้งหมดใหม่ใน onReceive หากไม่ดำเนินการนี้ จะไม่มีการปลุกใดๆ เกิดขึ้นหลังจากเปิดอุปกรณ์

ทำไมไม่แนะนำ setRepeating บน Android 4.4+?

ตั้งแต่ API 19 setRepeating ไม่แม่นยำอีกต่อไป — ระบบอาจเลื่อนช่วงเวลาเพื่อประหยัดพลังงาน ให้ใช้ setExact พร้อมกำหนดเวลาใหม่ด้วยตนเอง หรือ WorkManager พร้อม PeriodicWorkRequest ซึ่งให้พฤติกรรมที่คาดเดาได้มากกว่า

ต้องใช้สิทธิ์อะไรสำหรับการปลุกที่แม่นยำบน Android 12+?

สำหรับ setExact จำเป็นต้องมีสิทธิ์ SCHEDULE_EXACT_ALARM ซึ่งผู้ใช้สามารถให้หรือเพิกถอนได้ในการตั้งค่า สำหรับ setAlarmClock พร้อมการแสดงผลอินเทอร์เฟซนาฬิกา จะใช้ USE_EXACT_ALARM ซึ่งให้โดยอัตโนมัติเมื่อติดตั้งจากร้านค้า

สามารถใช้ AlarmManager โดยไม่มี PendingIntent ได้หรือไม่?

ไม่ AlarmManager ทำงานผ่าน PendingIntent เสมอ อาจเป็น PendingIntent.getBroadcast สำหรับ BroadcastReceiver, PendingIntent.getService สำหรับ Service หรือ PendingIntent.getActivity สำหรับ Activity หากไม่มี PendingIntent ระบบจะไม่สามารถส่งเหตุการณ์ไปยังแอปพลิเคชันได้

สรุป

  • AlarmManager เป็นบริการระบบ Android สำหรับทำงานตามเวลาที่แม่นยำพร้อมความสามารถในการปลุกอุปกรณ์
  • สี่ประเภท การปลุก — ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP และ RTC_WAKEUP — ครอบคลุมสถานการณ์ต่างๆ
  • setExact และ setAlarmClock เป็นเมธอดเดียวสำหรับการเรียกใช้ที่แม่นยำบน Android เวอร์ชันใหม่
  • setRepeating เลิกใช้แล้วบน Android 4.4+ — ใช้ setExact พร้อมกำหนดเวลาใหม่ด้วยตนเอง
  • สิทธิ์ SCHEDULE_EXACT_ALARM จำเป็นบน Android 12+ สำหรับการปลุกที่แม่นยำ
  • WorkManager หรือ JobScheduler เหมาะสำหรับงานพื้นหลังที่ไม่แม่นยำและไม่มีข้อกำหนดด้านเวลา
  • อย่าลืม จัดการ BOOT_COMPLETED เพื่อกู้คืนการปลุกหลังจากรีสตาร์ทอุปกรณ์

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม