ตั้งเวลาปลุก (original) (raw)

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

การปลุกมีลักษณะดังนี้

ตั้งปลุกแบบไม่ตรงเวลา

เมื่อแอปตั้ง_การปลุกที่ไม่แน่นอน_ ระบบจะส่งการปลุกในเวลาใดเวลาหนึ่ง ในอนาคต การปลุกที่ไม่แน่นอนจะรับประกันเวลาในการ นำส่งการปลุกบางอย่าง ในขณะที่ยังคงปฏิบัติตามข้อจำกัดในการประหยัดแบตเตอรี่ เช่น Doze

นักพัฒนาแอปสามารถใช้ประโยชน์จากการรับประกัน API ต่อไปนี้เพื่อปรับแต่งเวลาในการนำส่งการปลุกที่ไม่แน่นอน

ส่งเสียงปลุกหลังจากเวลาที่กำหนด

หากแอปเรียกใช้ set(),setInexactRepeating()หรือ setAndAllowWhileIdle()สัญญาณเตือนจะไม่ดังก่อนเวลาทริกเกอร์ที่ระบุ

ใน Android 12 (API ระดับ 31) ขึ้นไป ระบบจะเรียกใช้การปลุกภายใน 1 ชั่วโมงหลังจากเวลาทริกเกอร์ที่ระบุ เว้นแต่จะมีการจำกัดการประหยัดแบตเตอรี่ เช่น โหมดประหยัดแบตเตอรี่หรือโหมดพัก

ส่งการแจ้งเตือนในช่วงเวลาที่กำหนด

หากแอปเรียกใช้ setWindow() การปลุกจะไม่ทำงานก่อนเวลาทริกเกอร์ที่ระบุ หากไม่มีข้อจำกัดในการประหยัดแบตเตอรี่ การปลุกจะส่งภายในกรอบเวลาที่ระบุ โดยเริ่มจากเวลาทริกเกอร์ที่กำหนด

หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ระบบจะหน่วงเวลา การเรียกใช้การปลุกที่ไม่แน่นอนแบบช่วงเวลาอย่างน้อย 10 นาที ด้วยเหตุนี้ ค่าพารามิเตอร์ windowLengthMillis ภายใต้ 600000 จึงถูกตัดให้เหลือ 600000

ส่งการปลุกซ้ำในช่วงเวลาที่ค่อนข้างสม่ำเสมอ

หากแอปเรียกใช้ setInexactRepeating()ระบบจะเรียกใช้การปลุกหลายรายการ

  1. นาฬิกาปลุกแรกจะดังขึ้นภายในกรอบเวลาที่ระบุ โดยเริ่มจาก เวลาทริกเกอร์ที่ระบุ
  2. โดยปกติแล้ว นาฬิกาปลุกที่ตั้งไว้หลังจากนั้นจะดังขึ้นหลังจากช่วงเวลาที่ระบุผ่านไปแล้ว ระยะเวลาระหว่างการเรียกใช้การปลุก 2 ครั้งติดต่อกันอาจแตกต่างกันไป

ตั้งปลุกที่เวลาที่แน่นอน

ระบบจะเรียกใช้_การปลุกที่แน่นอน_ในเวลาที่แน่นอนในอนาคต

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

กรณีการใช้งานที่ไม่จำเป็นต้องใช้การปลุกในเวลาที่แน่นอน

รายการต่อไปนี้แสดงเวิร์กโฟลว์ทั่วไปที่อาจไม่กำหนดให้ใช้การตั้งปลุกในเวลาที่แน่นอน

การกำหนดเวลาการดำเนินการในช่วงอายุการใช้งานของแอป

คลาส Handler มีเมธอดดีๆ หลายอย่างสำหรับจัดการการดำเนินการตามเวลา เช่น การทำงานทุกๆ วินาทีขณะที่แอปทำงานอยู่postAtTime()และpostDelayed()โปรดทราบว่า API เหล่านี้ขึ้นอยู่กับเวลาทำงานของระบบไม่ใช่เรียลไทม์

งานพื้นหลังที่กำหนดเวลาไว้ เช่น การอัปเดตแอปและการอัปโหลดบันทึก

WorkManager มีวิธีกำหนดเวลาการทำงานเป็นระยะที่ต้องคำนึงถึงเวลาเป็นสำคัญคุณระบุช่วงเวลาซ้ำและ flexInterval (ขั้นต่ำ 15 นาที) เพื่อ กำหนดเวลาเรียกใช้แบบละเอียดสำหรับงานได้

การดำเนินการที่ผู้ใช้ระบุซึ่งควรเกิดขึ้นหลังจากเวลาที่เฉพาะเจาะจง (แม้ว่าระบบจะอยู่ในสถานะไม่ได้ใช้งาน)

ใช้การปลุกที่ไม่แน่นอน โดยเฉพาะโทรหาsetAndAllowWhileIdle()

การดำเนินการที่ผู้ใช้ระบุซึ่งควรเกิดขึ้นหลังจากเวลาที่เฉพาะเจาะจง

ใช้การปลุกที่ไม่แน่นอน โดยเฉพาะโทรหาset()

การกระทําที่ผู้ใช้ระบุซึ่งอาจเกิดขึ้นภายในกรอบเวลาที่ระบุ

ใช้การปลุกที่ไม่แน่นอน โดยเฉพาะโทรหาsetWindow()โปรดทราบว่าหากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ความยาวของหน้าต่างที่เล็กที่สุด ที่อนุญาตคือ 10 นาที

วิธีตั้งปลุกในเวลาที่แน่นอน

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

setExact()

เรียกใช้การปลุกในเวลาที่แม่นยำเกือบที่สุดในอนาคต ตราบใดที่ไม่ได้ใช้มาตรการประหยัดแบตเตอรี่อื่นๆ

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

setExactAndAllowWhileIdle()

เรียกใช้การปลุกในเวลาที่แม่นยำเกือบที่สุดในอนาคต แม้ว่าจะมีการใช้มาตรการประหยัดแบตเตอรี่ก็ตาม

setAlarmClock()

เรียกใช้การปลุกในเวลาที่แน่นอนในอนาคต เนื่องจากนาฬิกาปลุกเหล่านี้ มองเห็นได้ชัดเจนสำหรับผู้ใช้ ระบบจึงไม่ปรับเวลาการนำส่ง ระบบจะระบุการปลุกเหล่านี้ว่ามีความสำคัญมากที่สุด และจะออกจากโหมดประหยัดพลังงาน หากจำเป็นเพื่อส่งการปลุก

การใช้ทรัพยากรของระบบ

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

เราขอแนะนำอย่างยิ่งให้คุณสร้างการปลุกที่ไม่แน่นอนทุกครั้งที่ เป็นไปได้ หากต้องการทำงานนานขึ้น ให้กำหนดเวลาโดยใช้WorkManager หรือJobScheduler จากBroadcastReceiverของนาฬิกาปลุก หากต้องการทำงานขณะที่อุปกรณ์อยู่ในโหมดพัก ให้สร้างการปลุกในเวลาที่ไม่แน่นอนโดยใช้ setAndAllowWhileIdle() แล้วเริ่มงานจากการปลุก

ประกาศสิทธิ์การปลุกในเวลาที่แน่นอนที่เหมาะสม

หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป คุณต้องขอสิทธิ์เข้าถึงพิเศษของแอป "การปลุกและการช่วยเตือน" โดยประกาศสิทธิ์SCHEDULE_EXACT_ALARMในไฟล์ Manifest ของแอป ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

<manifest ...> <application ...> ...

หากแอปกำหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป คุณจะมีตัวเลือกในการ ประกาศสิทธิ์ SCHEDULE_EXACT_ALARMหรือสิทธิ์ USE_EXACT_ALARM

<manifest ...> <application ...> ...

แม้ว่าสิทธิ์ทั้ง SCHEDULE_EXACT_ALARM และ USE_EXACT_ALARM จะส่งสัญญาณความสามารถเดียวกัน แต่ก็มีการให้สิทธิ์ที่แตกต่างกันและรองรับกรณีการใช้งานที่ต่างกัน แอปของคุณควรใช้การปลุกในเวลาที่แน่นอน และประกาศสิทธิ์ SCHEDULE_EXACT_ALARM หรือ USE_EXACT_ALARM เฉพาะในกรณีที่ฟังก์ชันที่แสดงต่อผู้ใช้ในแอปของคุณต้องใช้การดำเนินการที่มีเวลาแน่นอน

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

ระบบไม่ได้ให้สิทธิ์ SCHEDULE_EXACT_ALARM ล่วงหน้าสำหรับการติดตั้งแอปใหม่ที่กำหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป หากผู้ใช้โอนข้อมูลแอป ไปยังอุปกรณ์ที่ใช้ Android 14 ผ่านการดำเนินการสำรองและกู้คืน ระบบจะปฏิเสธSCHEDULE_EXACT_ALARMสิทธิ์ในอุปกรณ์ใหม่ อย่างไรก็ตาม หากแอปที่มีอยู่มีสิทธิ์นี้อยู่แล้ว ระบบจะให้สิทธิ์ล่วงหน้าเมื่ออุปกรณ์อัปเกรดเป็น Android 14

หมายเหตุ: หากตั้งปลุกที่แน่นอนโดยใช้ออบเจ็กต์OnAlarmListener เช่น API setExact ก็ไม่จำเป็นต้องมีสิทธิ์ SCHEDULE_EXACT_ALARM

การใช้สิทธิ์ SCHEDULE_EXACT_ALARM

USE_EXACT_ALARM ต่างจาก SCHEDULE_EXACT_ALARM ตรงที่ผู้ใช้ต้องให้สิทธิ์ ทั้งผู้ใช้และระบบสามารถเพิกถอนสิทธิ์ SCHEDULE_EXACT_ALARM ได้

หากต้องการตรวจสอบว่าแอปได้รับสิทธิ์หรือไม่ ให้เรียกใช้canScheduleExactAlarms()ก่อนที่จะพยายามตั้งปลุกในเวลาที่แน่นอน เมื่อมีการเพิกถอนSCHEDULE_EXACT_ALARMสิทธิ์ สำหรับแอปของคุณ แอปจะหยุดทำงานและระบบจะยกเลิกการปลุกในเวลาที่แน่นอนทั้งหมดในอนาคต ซึ่งหมายความว่ามูลค่าที่ canScheduleExactAlarms() แสดงผลจะยังคงใช้ได้ตลอดวงจรของแอป

เมื่อแอปได้รับสิทธิ์ SCHEDULE_EXACT_ALARMS ระบบจะส่งการออกอากาศACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGEDให้แอป แอปของคุณควรใช้ Broadcast Receiver ที่ทำสิ่งต่อไปนี้

  1. ยืนยันว่าแอปของคุณยังคงมีสิทธิ์เข้าถึงแอปพิเศษ โดยโทรไปที่canScheduleExactAlarms()การตรวจสอบนี้จะปกป้องแอปของคุณในกรณีที่ผู้ใช้ให้สิทธิ์แก่แอป แล้วเพิกถอนสิทธิ์นั้นในเวลาต่อมา
  2. ตั้งเวลาปลุกที่แน่นอนใหม่ตามสถานะปัจจุบันของแอป ตรรกะนี้ควรคล้ายกับสิ่งที่แอปทำเมื่อได้รับACTION_BOOT_COMPLETEDการออกอากาศ

ขอให้ผู้ใช้ให้สิทธิ์ SCHEDULE_EXACT_ALARM

ตัวเลือกนี้เรียกว่า "อนุญาตให้ตั้งปลุกและการช่วยเตือน"

รูปที่ 1 หน้าสิทธิ์เข้าถึงพิเศษของแอป "การปลุกและการช่วยเตือน" ในการตั้งค่าระบบ ซึ่งผู้ใช้สามารถอนุญาตให้แอปตั้งค่าการปลุกที่แน่นอนได้

หากจำเป็น คุณสามารถส่งผู้ใช้ไปยังหน้าจอการปลุกและการช่วยเตือนในการตั้งค่าระบบ ได้ ดังที่แสดงในรูปที่ 1 โดยทำตามขั้นตอนต่อไปนี้

  1. ใน UI ของแอป ให้อธิบายแก่ผู้ใช้ถึงสาเหตุที่แอปของคุณต้องตั้งเวลาปลุกที่แน่นอน
  2. เรียกใช้ Intent ที่มีACTION_REQUEST_SCHEDULE_EXACT_ALARMการดำเนินการของ Intent

ตั้งปลุกซ้ำ

การปลุกซ้ำช่วยให้ระบบแจ้งเตือนแอปของคุณตามกำหนดเวลาที่เกิดซ้ำได้

การปลุกที่ออกแบบมาไม่ดีอาจทำให้แบตเตอรี่หมดและสร้างภาระงานอย่างหนักในเซิร์ฟเวอร์ ด้วยเหตุนี้ ใน Android 4.4 (API ระดับ 19) ขึ้นไป การปลุกที่ทำซ้ำทั้งหมดจึงเป็นการปลุกที่ไม่แน่นอน

การปลุกซ้ำมีลักษณะดังนี้

หากต้องการยกเลิก PendingIntent() ให้ส่งFLAG_NO_CREATEไปยัง PendingIntent.getService()เพื่อรับอินสแตนซ์ของ Intent (หากมี) จากนั้นส่ง Intent นั้นไปยังAlarmManager.cancel()

Kotlin

val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager val pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE) if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent) }

Java

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent); }

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

สิ่งแรกๆ ที่ควรพิจารณาในการใช้นาฬิกาปลุกที่ตั้งซ้ำคือประเภทของนาฬิกาปลุก

นาฬิกาปลุกมีนาฬิกา 2 ประเภทหลักๆ ได้แก่ "เวลาจริงที่ผ่านไป" และ "นาฬิกาเวลาจริง" (RTC) เวลาจริงที่ผ่านไปใช้ "เวลาตั้งแต่ระบบบูต" เป็นข้อมูลอ้างอิง และนาฬิกาเวลาจริงใช้เวลา UTC (นาฬิกาติดผนัง) ซึ่งหมายความว่า เวลาจริงที่ผ่านไปเหมาะกับการตั้งปลุกตามเวลาที่ผ่านไป (เช่น การปลุกที่ดังทุกๆ 30 วินาที) เนื่องจากไม่ได้รับผลกระทบจาก เขตเวลาหรือภาษา ประเภทนาฬิกาแบบเรียลไทม์เหมาะสำหรับนาฬิกาปลุกที่ ขึ้นอยู่กับภาษาปัจจุบันมากกว่า

ทั้ง 2 ประเภทมีเวอร์ชัน "ปลุก" ซึ่งจะสั่งให้ปลุก CPU ของอุปกรณ์หาก หน้าจอปิดอยู่ เพื่อให้มั่นใจว่าการปลุกจะทำงานตามเวลาที่กำหนด วิธีนี้มีประโยชน์หากแอปของคุณมีทรัพยากร Dependency ที่ขึ้นอยู่กับเวลา เช่น หากมีระยะเวลาจำกัดในการดำเนินการบางอย่าง หากคุณไม่ได้ใช้ เวอร์ชันปลุกของประเภทการปลุก นาฬิกาปลุกที่ตั้งซ้ำทั้งหมดจะดัง เมื่ออุปกรณ์ตื่นขึ้นในครั้งถัดไป

หากคุณเพียงต้องการให้การปลุกทำงานในช่วงเวลาที่เฉพาะเจาะจง (เช่น ทุกครึ่งชั่วโมง) ให้ใช้ประเภทเวลาจริงที่ผ่านไปแล้วประเภทใดประเภทหนึ่ง โดยทั่วไปแล้ว ตัวเลือกนี้ เป็นตัวเลือกที่ดีกว่า

หากต้องการให้การปลุกทำงานในเวลาที่เฉพาะเจาะจงของวัน ให้เลือกประเภทนาฬิกาแบบเรียลไทม์ที่อิงตามนาฬิกา อย่างไรก็ตาม โปรดทราบว่าวิธีนี้อาจมีข้อเสียบางประการ แอปอาจแปลเป็นภาษาอื่นๆ ได้ไม่ดี และหากผู้ใช้เปลี่ยนการตั้งค่าเวลาของอุปกรณ์ อาจทำให้แอปทำงานผิดปกติได้ การใช้นาฬิกาเรียลไทม์เป็นประเภทการปลุกยังปรับขนาดได้ไม่ดีตามที่อธิบายไว้ข้างต้น เราขอแนะนำให้คุณใช้นาฬิกาปลุก "เวลาจริงที่ผ่านไป" หากทำได้

รายการประเภทมีดังนี้

ตัวอย่างการปลุกแบบเรียลไทม์ที่ผ่านไปแล้ว

ตัวอย่างการใช้ ELAPSED_REALTIME_WAKEUP มีดังนี้

ปลุกอุปกรณ์เพื่อตั้งปลุกในอีก 30 นาที และทุกๆ 30 นาทีหลังจากนั้น

Kotlin

// Hopefully your alarm will have a lower frequency than this! alarmMgr?.setInexactRepeating( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent )

Java

// Hopefully your alarm will have a lower frequency than this! alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

ปลุกอุปกรณ์เพื่อตั้งปลุกแบบครั้งเดียว (ไม่ซ้ำ) ใน 1 นาที

Kotlin

private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) }

alarmMgr?.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent )

Java

private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);

ตัวอย่างการปลุกของนาฬิกาแบบเรียลไทม์

ตัวอย่างการใช้RTC_WAKEUPมีดังนี้

ปลุกอุปกรณ์เพื่อตั้งปลุกเวลาประมาณ 14:00 น. และ ทำซ้ำวันละครั้งในเวลาเดียวกัน

Kotlin

// Set the alarm to start at approximately 2:00 p.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 14) }

// With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr?.setInexactRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, AlarmManager.INTERVAL_DAY, alarmIntent )

Java

// Set the alarm to start at approximately 2:00 p.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);

ปลุกอุปกรณ์เพื่อตั้งปลุกเวลา 08:30 น. ตรง และทุกๆ 20 นาทีหลังจากนั้น

Kotlin

private var alarmMgr: AlarmManager? = null private lateinit var alarmIntent: PendingIntent ... alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent -> PendingIntent.getBroadcast(context, 0, intent, 0) }

// Set the alarm to start at 8:30 a.m. val calendar: Calendar = Calendar.getInstance().apply { timeInMillis = System.currentTimeMillis() set(Calendar.HOUR_OF_DAY, 8) set(Calendar.MINUTE, 30) }

// setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr?.setRepeating( AlarmManager.RTC_WAKEUP, calendar.timeInMillis, 1000 * 60 * 20, alarmIntent )

Java

private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 8); calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 20, alarmIntent);

เลือกระดับความแม่นยำของนาฬิกาปลุก

ดังที่ได้อธิบายไว้ก่อนหน้านี้ การเลือกประเภทการปลุกมักเป็นขั้นตอนแรกในการ สร้างการปลุก ความแตกต่างอีกอย่างคือคุณต้องการให้การปลุก มีความแม่นยำมากน้อยเพียงใด สำหรับแอปส่วนใหญ่setInexactRepeating()เป็นตัวเลือกที่เหมาะสม เมื่อใช้วิธีนี้ Android จะซิงค์การปลุกที่ทำซ้ำหลายรายการที่ไม่แน่นอนและเรียกใช้ พร้อมกัน ซึ่งจะช่วยลดการเปลืองแบตเตอรี่

หลีกเลี่ยงการใช้การปลุกในเวลาที่แน่นอนหากเป็นไปได้ อย่างไรก็ตาม สำหรับแอปที่พบได้น้อยซึ่งมีข้อกำหนดด้านเวลาที่เข้มงวด คุณสามารถตั้งการปลุกที่แน่นอนได้โดยเรียกใช้ setRepeating()

เมื่อใช้ setInexactRepeating()คุณจะระบุช่วงเวลาที่กำหนดเองไม่ได้เหมือนกับที่ทำได้ใน setRepeating()คุณต้องใช้ค่าคงที่ช่วงเวลาอย่างใดอย่างหนึ่ง เช่นINTERVAL_FIFTEEN_MINUTES INTERVAL_DAY เป็นต้น ดูรายการทั้งหมดได้ที่ AlarmManager

ยกเลิกการปลุก

คุณอาจต้องรวมความสามารถในการยกเลิกการปลุกไว้ด้วย ทั้งนี้ขึ้นอยู่กับแอป หากต้องการยกเลิกการปลุก ให้เรียกใช้ cancel()ใน Alarm Manager โดยส่ง PendingIntent ที่คุณไม่ต้องการ ให้ทริกเกอร์อีกต่อไป เช่น

Kotlin

// If the alarm has been set, cancel it. alarmMgr?.cancel(alarmIntent)

Java

// If the alarm has been set, cancel it. if (alarmMgr!= null) { alarmMgr.cancel(alarmIntent); }

ตั้งปลุกเมื่ออุปกรณ์รีสตาร์ท

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

มีขั้นตอนดังนี้

  1. ตั้งค่าสิทธิ์ RECEIVE_BOOT_COMPLETED ในไฟล์ Manifest ของแอปพลิเคชัน ซึ่งจะช่วยให้แอปได้รับACTION_BOOT_COMPLETEDที่ออกอากาศหลังจากที่ระบบบูตเสร็จสิ้น (การดำเนินการนี้จะใช้ได้ก็ต่อเมื่อผู้ใช้ได้เปิดแอปอย่างน้อย 1 ครั้งแล้วเท่านั้น)
  2. ใช้BroadcastReceiverเพื่อรับการออกอากาศ

Kotlin

class SampleBootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "android.intent.action.BOOT_COMPLETED") {
// Set the alarm here.
}
}
}

Java

public class SampleBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
}
}
} 3. เพิ่มตัวรับลงในไฟล์ Manifest ของแอปด้วยตัวกรอง Intent ที่ กรองตามACTION_BOOT_COMPLETEDการดำเนินการ





โปรดทราบว่าในไฟล์ Manifest ตัวรับสัญญาณการบูตจะตั้งค่าเป็นandroid:enabled="false" ซึ่งหมายความว่าจะไม่มีการเรียกใช้ตัวรับ เว้นแต่แอปพลิเคชันจะเปิดใช้โดยชัดแจ้ง ซึ่งจะป้องกันไม่ให้มีการเรียกใช้ ตัวรับสัญญาณการบูตโดยไม่จำเป็น คุณเปิดใช้ตัวรับ (เช่น หากผู้ใช้ตั้งปลุก) ได้ดังนี้

Kotlin

val receiver = ComponentName(context, SampleBootReceiver::class.java)
context.packageManager.setComponentEnabledSetting(
receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)

Java

ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
เมื่อเปิดใช้ตัวรับสัญญาณด้วยวิธีนี้แล้ว ตัวรับสัญญาณจะยังคงเปิดใช้ต่อไปแม้ว่าผู้ใช้จะรีบูตอุปกรณ์ก็ตาม กล่าวคือ การเปิดใช้ตัวรับสัญญาณโดยใช้โปรแกรมจะลบล้างการตั้งค่า Manifest แม้จะรีบูตก็ตาม ตัวรับจะยังคง เปิดใช้จนกว่าแอปจะปิดใช้ คุณปิดใช้ตัวรับได้ (เช่น หากผู้ใช้ยกเลิกการปลุก) โดยทำดังนี้

Kotlin

val receiver = ComponentName(context, SampleBootReceiver::class.java)
context.packageManager.setComponentEnabledSetting(
receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP
)

Java

ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);

เรียกใช้การปลุกขณะที่อุปกรณ์อยู่ในโหมดพัก

อุปกรณ์ที่ใช้ Android 6.0 (API ระดับ 23) รองรับโหมดพักเครื่อง ซึ่งจะช่วยยืดอายุการใช้งานแบตเตอรี่ของอุปกรณ์ นาฬิกาปลุกจะไม่ทำงานเมื่ออุปกรณ์อยู่ในโหมดพักเครื่องระบบจะเลื่อนการปลุกที่กำหนดเวลาไว้จนกว่าอุปกรณ์จะออกจากโหมดพักเครื่อง หากต้องการ ทำงานให้เสร็จแม้ในขณะที่อุปกรณ์ไม่ได้ใช้งาน คุณมีตัวเลือกหลายอย่าง ดังนี้

แนวทางปฏิบัติแนะนำ

ทุกตัวเลือกที่คุณเลือกในการออกแบบนาฬิกาปลุกที่ปลุกซ้ำอาจส่งผลต่อวิธีที่แอปใช้ (หรือละเมิด) ทรัพยากรของระบบ ตัวอย่างเช่น ลองนึกถึง แอปยอดนิยมที่ซิงค์กับเซิร์ฟเวอร์ หากการดำเนินการซิงค์อิงตามเวลา และทุกอินสแตนซ์ของแอปจะซิงค์เวลา 23:00 น. ภาระงานใน เซิร์ฟเวอร์อาจทำให้เกิดเวลาในการตอบสนองสูงหรือแม้แต่ "การปฏิเสธการให้บริการ" ทำตามแนวทางปฏิบัติแนะนำต่อไปนี้ในการใช้นาฬิกาปลุก