AlarmManager
) จะบอกให้คุณทราบถึงวิธีการ
การดำเนินการที่อิงตามเวลานอกเหนือจากอายุการใช้งานของแอปพลิเคชัน
ตัวอย่างเช่น คุณสามารถใช้การปลุกเพื่อเริ่มการดำเนินการที่ยาวนาน เช่น
เป็นการเริ่มบริการวันละครั้งเพื่อดาวน์โหลดพยากรณ์อากาศ
การปลุกมีลักษณะดังต่อไปนี้
เมตริกเหล่านี้ให้คุณเริ่มการทำงานของ Intent ในเวลาที่กำหนดและ/หรือตามช่วงเวลา
คุณสามารถใช้ Chromecast ร่วมกับ Broadcast Receiver เพื่อกำหนดเวลา jobs หรือ WorkRequests เพื่อดำเนินการอื่นๆ การดำเนินงาน
โดยจะทำงานนอกแอปพลิเคชัน คุณจึงใช้เพื่อทริกเกอร์ได้ เหตุการณ์หรือการทำงานใดๆ แม้ในขณะที่แอปของคุณไม่ได้ทำงานอยู่ และแม้ว่าอุปกรณ์ หลับสบาย
ซึ่งช่วยลดความต้องการทรัพยากรของแอปให้เหลือน้อยที่สุด คุณจะกำหนดเวลาได้ โดยไม่ต้องอาศัยตัวจับเวลาหรือบริการที่กำลังทำงานอย่างต่อเนื่อง
ตั้งปลุกที่ไม่แน่นอน
เมื่อแอปตั้งการปลุกที่ไม่แม่นยำ ระบบจะส่งการปลุกในเวลาใดเวลาหนึ่ง ในอนาคต การปลุกในเวลาที่ไม่แน่นอนให้การรับประกันบางประการเกี่ยวกับช่วงเวลาของ ส่งสัญญาณเตือนโดยปฏิบัติตามข้อจำกัดการประหยัดแบตเตอรี่ เช่น Doze
นักพัฒนาแอปสามารถใช้ประโยชน์จากการรับประกัน API ต่อไปนี้เพื่อปรับแต่งช่วงเวลาของ การส่งการแจ้งเตือนที่ไม่แม่นยำ
ส่งการปลุกหลังเวลาที่กำหนด
หากแอปเรียกใช้ set()
setInexactRepeating()
,
หรือ setAndAllowWhileIdle()
สัญญาณเตือนจะไม่ดังก่อนเวลาทริกเกอร์ที่ระบุ
ใน Android 12 (API ระดับ 31) ขึ้นไป ระบบจะเรียกใช้การปลุกภายใน 1 ชั่วโมงของเวลาทริกเกอร์ที่ระบุ ยกเว้นว่าจะมีข้อจำกัดในการประหยัดแบตเตอรี่ เช่น โหมดประหยัดแบตเตอรี่ หรือ Doze
ส่งสัญญาณเตือนในกรอบเวลา
หากแอปโทรหา setWindow()
การปลุกจะไม่ส่งเสียงก่อนที่จะให้สัญญาณ
เวลาในการทริกเกอร์ การปลุกจะเป็น เว้นแต่มีข้อจำกัดในการประหยัดแบตเตอรี่มีผลบังคับใช้
แสดงภายในกรอบเวลาที่ระบุ โดยเริ่มต้นจากทริกเกอร์ที่กำหนด
หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ระบบอาจหน่วงเวลา
การเรียกใช้การปลุกในเวลาที่แน่นอนที่มีกรอบเวลานานอย่างน้อย 10 นาที สำหรับ
ด้วยเหตุนี้ ค่าพารามิเตอร์ windowLengthMillis
ภายใต้ 600000
จึงถูกตัดเป็น
600000
ตั้งปลุกซ้ำในช่วงเวลาที่สม่ำเสมอโดยประมาณ
หากแอปเรียกใช้ setInexactRepeating()
ระบบจะตั้งปลุกหลายรายการ:
- การปลุกครั้งแรกจะดังภายในกรอบเวลาที่ระบุ โดยเริ่มตั้งแต่ เวลาทริกเกอร์ที่กำหนด
- การปลุกครั้งต่อๆ ไปมักจะส่งเสียงเตือนหลังจากกรอบเวลาที่ระบุไว้ ผ่านไปแล้ว เวลาระหว่างการเรียกใช้การปลุกติดต่อกัน 2 ครั้งอาจแตกต่างกัน
ตั้งปลุกในเวลาที่แน่นอน
ระบบจะเรียกใช้การปลุกในเวลาที่แน่นอนในอนาคต
แอปส่วนใหญ่กำหนดเวลางานและกิจกรรมโดยใช้การปลุกที่ไม่เหมือนกันเพื่อ กรอก Use Case ทั่วไปหลายๆ รายการ หากหัวใจของแอป ฟังก์ชันการทำงานจะขึ้นอยู่กับการปลุกที่มีเวลาแน่นอน เช่น แอปนาฬิกาปลุก หรือแอปปฏิทิน จะใช้การปลุกในเวลาที่แน่นอนแทนก็ได้
กรณีการใช้งานที่อาจไม่ต้องการการปลุกในเวลาที่แน่นอน
รายการต่อไปนี้แสดงเวิร์กโฟลว์ทั่วไปที่อาจไม่ต้องการการปลุกในเวลาที่แน่นอน
- การกำหนดเวลาดำเนินการในระหว่างอายุการใช้งานของแอป
- ชั้นเรียน
Handler
มีหลายเนื้อหา ในการจัดการการดำเนินงานด้านเวลา เช่น ทำงานบางอย่าง n วินาที ขณะที่แอปทำงานอยู่postAtTime()
และpostDelayed()
โปรดทราบว่า API เหล่านี้ต้องใช้ระยะเวลาทำงานของระบบ ไม่ใช่แบบเรียลไทม์ - งานในเบื้องหลังที่กำหนดเวลาไว้ เช่น การอัปเดตแอปและอัปโหลดบันทึก
WorkManager
มอบวิธีกำหนดเวลาสำหรับช่วงเวลาที่มีความละเอียดอ่อน ที่ทำงาน คุณสามารถระบุช่วงการทำซ้ำและflexInterval
(ขั้นต่ำ 15 นาที) เพื่อ กำหนดรันไทม์แบบละเอียดสำหรับงาน- การดำเนินการที่ผู้ใช้ระบุที่ควรเกิดขึ้นหลังจากเวลาหนึ่งๆ (แม้ว่าระบบจะอยู่ในสถานะไม่มีการใช้งาน)
- ใช้การปลุกในเวลาที่ไม่แน่นอน กล่าวอย่างเจาะจงคือ
setAndAllowWhileIdle()
- การดำเนินการที่ผู้ใช้ระบุที่ควรเกิดขึ้นหลังจากเวลาที่ระบุ
- ใช้การปลุกในเวลาที่ไม่แน่นอน กล่าวอย่างเจาะจงคือ
set()
- การดำเนินการที่ผู้ใช้ระบุซึ่งอาจเกิดขึ้นได้ภายในกรอบเวลาที่ระบุ
- ใช้การปลุกในเวลาที่ไม่แน่นอน กล่าวอย่างเจาะจงคือ
setWindow()
โปรดทราบว่าหากแอปกําหนดเป้าหมายเป็น Android 12 ขึ้นไป กลุ่มเป้าหมายที่มีขนาดเล็กที่สุด ความยาวของช่วงเวลาที่อนุญาตคือ 10 นาที
วิธีตั้งปลุกในเวลาที่แน่นอน
แอปของคุณตั้งปลุกในเวลาที่แน่นอนได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้ วิธีการเหล่านี้ ถูกเรียงลำดับเพื่อให้รายการที่อยู่ใกล้ด้านล่างสุดแสดงรายการมากกว่า งานที่ต้องแข่งกับเวลา ต้องใช้ทรัพยากรระบบมากขึ้น
setExact()
เรียกใช้การปลุกในเวลาที่ใกล้เคียงกับเวลาอื่นๆ ในอนาคต มาตรการประหยัดแบตเตอรี่จะไม่มีผล
ใช้วิธีนี้เพื่อตั้งปลุกในเวลาที่แน่นอน เว้นแต่แอปจะทำงาน ในช่วงเวลาสำคัญสำหรับผู้ใช้
setExactAndAllowWhileIdle()
เรียกใช้การปลุกในเวลาที่แน่นอนในอนาคต แม้ว่าโหมดนี้จะประหยัดแบตเตอรี่ก็ตาม และมาตรการต่างๆ ที่มีผลบังคับใช้
setAlarmClock()
เรียกใช้การปลุกในเวลาที่แน่นอนในอนาคต เพราะการตั้งปลุกเหล่านี้ ระบบจึงไม่เคยปรับเวลานำส่งผู้ใช้จะเห็นได้อย่างชัดเจน ระบบระบุว่าสัญญาณเตือนเหล่านี้เป็นการปลุกที่สำคัญที่สุดและใช้พลังงานต่ำ โหมดนี้หากจำเป็นต่อการส่งการแจ้งเตือน
การใช้ทรัพยากรระบบ
เมื่อระบบเรียกใช้การปลุกในเวลาที่แน่นอนที่แอปของคุณตั้งไว้ อุปกรณ์ ใช้ทรัพยากรอย่างมาก เช่น อายุการใช้งานแบตเตอรี่ โดยเฉพาะหากอุปกรณ์อยู่ใน โหมดประหยัดพลังงาน นอกจากนี้ ระบบไม่สามารถจัดกลุ่มคำขอเหล่านี้ เพื่อให้ใช้ทรัพยากรได้อย่างมีประสิทธิภาพมากขึ้น
เราขอแนะนำให้คุณสร้างการปลุกในเวลาที่ไม่แน่นอนได้ทุกเมื่อ
เท่าที่จะเป็นไปได้ หากต้องการทำงานที่นานขึ้น ให้ตั้งเวลาโดยใช้
WorkManager
หรือ
JobScheduler
จากการปลุก
BroadcastReceiver
ทำงานในขณะที่
อุปกรณ์อยู่ใน Doze สร้างการปลุกที่ไม่แน่นอนโดยใช้
setAndAllowWhileIdle()
และเริ่มงานจากนาฬิกาปลุก
ประกาศสิทธิ์การปลุกในเวลาที่แน่นอนที่เหมาะสม
หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป คุณต้องมี
"นาฬิกาปลุกและ ช่วยเตือน" สิทธิ์เข้าถึงพิเศษของแอป โดยประกาศ
SCHEDULE_EXACT_ALARM
สิทธิ์ในไฟล์ Manifest ของแอปตามที่แสดงในข้อมูลโค้ดต่อไปนี้
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
หากแอปกำหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป คุณจะมีตัวเลือกให้
ประกาศ SCHEDULE_EXACT_ALARM
หรือ USE_EXACT_ALARM
สิทธิ์
<manifest ...> <uses-permission android:name="android.permission.USE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
แม้ว่าทั้งสิทธิ์ SCHEDULE_EXACT_ALARM
และ USE_EXACT_ALARM
ส่งสัญญาณถึงความสามารถเดียวกัน มีความสามารถที่แตกต่างกัน และสนับสนุนแตกต่างกัน
กรณีการใช้งาน แอปควรใช้การปลุกในเวลาที่แน่นอน และประกาศอย่างใดอย่างหนึ่งต่อไปนี้
สิทธิ์ SCHEDULE_EXACT_ALARM
หรือ USE_EXACT_ALARM
ก็ต่อเมื่อผู้ใช้มองเห็น
ในแอปของคุณต้องมีการดำเนินการที่มีเวลาแน่นอน
USE_EXACT_ALARM
- ให้สิทธิ์โดยอัตโนมัติ
- ผู้ใช้เพิกถอนไม่ได้
- ขึ้นอยู่กับนโยบาย Google Play ที่กำลังจะเกิดขึ้น
- กรณีการใช้งานที่จำกัด
SCHEDULE_EXACT_ALARM
- ให้สิทธิ์จากผู้ใช้
- กรณีการใช้งานที่หลากหลายขึ้น
- แอปควรยืนยันว่ายังไม่มีการเพิกถอนสิทธิ์
สิทธิ์ SCHEDULE_EXACT_ALARM
ไม่ได้รับการให้สิทธิ์ล่วงหน้าสำหรับการติดตั้งใหม่ของ
แอปที่กำหนดเป้าหมายเป็น Android 13 (API ระดับ 33) ขึ้นไป หากผู้ใช้โอนแอป
ไปยังอุปกรณ์ที่ใช้ Android 14 ผ่านการดำเนินการสำรองและกู้คืนข้อมูล
สิทธิ์เข้าถึง SCHEDULE_EXACT_ALARM
จะถูกปฏิเสธในอุปกรณ์ใหม่ อย่างไรก็ตาม หาก
แอปที่มีอยู่มีสิทธิ์นี้อยู่แล้ว โดยจะให้สิทธิ์ล่วงหน้าเมื่อ
ที่อัปเกรดเป็น Android 14
หมายเหตุ: หากตั้งปลุกในเวลาที่แน่นอนโดยใช้
OnAlarmListener
เช่น
setExact
API ไม่จําเป็นต้องใช้สิทธิ์ 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
ออกอากาศ แอปของคุณควรใช้การออกอากาศ
รีซีฟเวอร์ที่ทำหน้าที่
ดังต่อไปนี้:
- ยืนยันว่าแอปของคุณยังคงมีสิทธิ์เข้าถึงพิเศษของแอป โดยโทร
canScheduleExactAlarms()
การตรวจสอบนี้จะปกป้องแอปของคุณจากกรณีที่ผู้ใช้ให้สิทธิ์แอปของคุณ แล้วก็เพิกถอนสิทธิ์นั้นหลังจากนั้นเกือบจะทันที - ตั้งเวลาปลุกที่แน่นอนที่แอปต้องการใหม่ โดยอิงตามสถานะปัจจุบันของแอป
ตรรกะนี้ควรคล้ายกับสิ่งที่แอปของคุณทำเมื่อได้รับ
ACTION_BOOT_COMPLETED
ออกอากาศ
ขอให้ผู้ใช้ให้สิทธิ์ SCHEDULE_EXACT_ALARM
หากจำเป็น คุณสามารถส่งผู้ใช้ไปที่การปลุกและ หน้าจอการช่วยเตือนในระบบ การตั้งค่า ดังที่แสดงในรูปที่ 1 โดยทำตามขั้นตอนต่อไปนี้
- ใน UI ของแอป ให้อธิบายให้ผู้ใช้ทราบว่าทำไมแอปของคุณจึงต้องตั้งเวลา การปลุก
- เรียกใช้ Intent ที่มีเมธอด
ACTION_REQUEST_SCHEDULE_EXACT_ALARM
การดำเนินการผ่าน Intent
ตั้งปลุกซ้ำ
การปลุกซ้ำช่วยให้ระบบแจ้งเตือนแอปที่เกิดซ้ำ กำหนดการ
การปลุกที่ออกแบบมาไม่ดีอาจทำให้แบตเตอรี่หมดเร็วและทำให้อุปกรณ์ทำงานหนักเกินไป เซิร์ฟเวอร์ ด้วยเหตุนี้ ใน Android 4.4 (API ระดับ 19) ขึ้นไปทั้งหมด การปลุกซ้ำเป็นการปลุกที่ไม่แน่ชัด
การปลุกซ้ำมีลักษณะดังต่อไปนี้
ประเภทการปลุก สำหรับการสนทนาเพิ่มเติม โปรดดูที่เลือกประเภทการปลุก
เวลาทริกเกอร์ หากเวลาทริกเกอร์ที่คุณระบุเป็นเวลาที่ผ่านมาแล้ว ทริกเกอร์ทันที
ช่วงเวลาของการปลุก เช่น วันละครั้ง ทุกชั่วโมง หรือทุก 5 นาที
ความตั้งใจที่รอดำเนินการที่จะเริ่มทำงานเมื่อมีการเรียกให้ปลุก เมื่อคุณตั้งค่า การปลุกครั้งที่ 2 ที่ใช้ Intent ที่รอดำเนินการเดียวกัน การปลุกนี้จะแทนที่การปลุกเดิม
หากต้องการยกเลิก 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 ของอุปกรณ์" หน้าจอปิดแล้ว ซึ่งจะทำให้การปลุกเริ่มทำงานตามเวลาที่กำหนดไว้ วิธีนี้มีประโยชน์หากแอปของคุณมีการอ้างอิงเวลา เช่น หากมี หน้าต่างที่จำกัดเพื่อดำเนินการอย่างใดอย่างหนึ่ง หากไม่ได้ใช้ ประเภทการปลุกเป็นการปลุกระบบ จากนั้นการปลุกซ้ำทั้งหมดจะเริ่มทํางาน เมื่อเปิดอุปกรณ์อีกครั้ง
หากคุณต้องการเพียงแค่ให้นาฬิกาปลุกเริ่มทำงานที่ช่วงเวลาใดเวลาหนึ่ง (ตัวอย่างเช่น ทุกครึ่งชั่วโมง) ให้ใช้ประเภทแบบเรียลไทม์ที่ผ่านไป โดยทั่วไป ค่านี้ เป็นทางเลือกที่ดีกว่า
หากคุณต้องการให้นาฬิกาปลุกเริ่มทำงานในเวลาใดเวลาหนึ่งของวัน ให้เลือกการปลุก ประเภทต่างๆ ของนาฬิกาแบบเรียลไทม์ แต่โปรดทราบว่าวิธีนี้อาจ มีข้อเสียบางอย่าง แอปอาจแปลเป็นภาษาอื่นได้ไม่ดีนัก และ ผู้ใช้เปลี่ยนการตั้งค่าเวลาของอุปกรณ์ จึงอาจทำให้เกิดลักษณะการทำงานที่ไม่คาดคิด ในแอปของคุณ นอกจากนี้ การใช้ประเภทนาฬิกาปลุกแบบเรียลไทม์ก็ปรับขยายขนาดได้ไม่ดีนัก เช่น ที่กล่าวถึงข้างต้น เราขอแนะนำให้ใช้ "เรียลไทม์ที่ผ่านไปแล้ว" การปลุก ถ้าทำได้
ประเภทรายการมีดังนี้
ELAPSED_REALTIME
: เริ่มการทำงานของ Intent ที่รอดําเนินการโดยอิงตามระยะเวลานับตั้งแต่อุปกรณ์ เปิดเครื่องแล้ว แต่ไม่ได้ปลุกระบบอุปกรณ์ เวลาที่ผ่านไปรวมถึงช่วงเวลาที่อุปกรณ์อยู่ในโหมดสลีปELAPSED_REALTIME_WAKEUP
: ปลุกอุปกรณ์และเริ่ม Intent ที่รอดำเนินการหลังจากระยะเวลาที่ระบุ ของเวลาผ่านไปนับตั้งแต่การบูตอุปกรณ์RTC
: เริ่มการทำงานของ Intent ที่ค้างอยู่ในเวลาที่ระบุ แต่ไม่ปลุกระบบอุปกรณ์RTC_WAKEUP
: ตื่น ให้อุปกรณ์เริ่มการทำงานของ Intent ที่รอดำเนินการในเวลาที่กำหนด
ตัวอย่างการปลุกแบบเรียลไทม์ที่ผ่านไป
ต่อไปนี้คือตัวอย่างการใช้ 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 ครั้ง (แบบไม่ซ้ำ) ใน 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);
ปลุกให้อุปกรณ์ส่งเสียงปลุกในเวลา 8: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
จะ
ที่จะทำงานต่อได้โดยที่ผู้ใช้ไม่ต้องเริ่มการปลุกอีกครั้งด้วยตนเอง
มีขั้นตอนดังนี้
ตั้งค่า
RECEIVE_BOOT_COMPLETED
สิทธิ์ในไฟล์ Manifest ของแอปพลิเคชัน วิธีนี้ช่วยให้แอปของคุณได้รับACTION_BOOT_COMPLETED
ที่จะออกอากาศหลังจากระบบบูตเสร็จสิ้น (วิธีนี้จะใช้ได้ต่อเมื่อ ได้เปิดให้บริการโดยผู้ใช้แล้วอย่างน้อย 1 ครั้ง) ดังนี้<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
ใช้
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. } } }
เพิ่มตัวรับสัญญาณลงในไฟล์ Manifest ของแอปด้วยตัวกรอง Intent ตัวกรองใน
ACTION_BOOT_COMPLETED
การดำเนินการ:<receiver android:name=".SampleBootReceiver" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver>
โปรดสังเกตว่าในไฟล์ 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);
เรียกใช้การปลุกขณะที่อุปกรณ์อยู่ในโหมด Doze
อุปกรณ์ที่ใช้การสนับสนุน Android 6.0 (API ระดับ 23) Doze ช่วยยืดอายุการใช้งานแบตเตอรี่ของอุปกรณ์ การปลุกจะไม่ส่งเสียงเมื่ออุปกรณ์เปิดอยู่ โหมด Doze ระบบจะเลื่อนการปลุกที่กำหนดเวลาไว้จนกว่าอุปกรณ์จะออกจาก Doze หากคุณจำเป็นต้องทำดังนี้ สามารถทำงานได้อย่างสมบูรณ์ แม้ในขณะที่อุปกรณ์ไม่มีการใช้งาน มีหลายตัวเลือกดังนี้ ว่าง:
ใช้ WorkManager API ที่สร้างขึ้นเพื่อทำงาน งานที่ทำอยู่เบื้องหลัง คุณสามารถระบุว่าระบบควร เร่งการทำงานของคุณ เพื่อให้งานเสร็จโดยเร็วที่สุด สำหรับข้อมูลเพิ่มเติม โปรดดู กำหนดเวลางานด้วย WorkManager
แนวทางปฏิบัติแนะนำ
ทุกตัวเลือกที่คุณเลือกในการออกแบบการปลุกซ้ำอาจส่งผลตามมา วิธีที่แอปของคุณใช้ (หรือละเมิด) ทรัพยากรระบบ ตัวอย่างเช่น สมมติว่า แอปยอดนิยมที่ซิงค์กับเซิร์ฟเวอร์ หากการดำเนินการซิงค์อ้างอิงตามนาฬิกา และทุกๆ อินสแตนซ์ของแอปจะซิงค์เวลา 23:00 น. ของการโหลด อาจทำให้ใช้เวลาในการตอบสนองนาน "ปฏิเสธการให้บริการ" ทำตามแนวทางปฏิบัติแนะนำต่อไปนี้ในการใช้การปลุก
เพิ่มการสุ่ม (Jitter) ลงในคําขอเครือข่าย ทริกเกอร์เนื่องจากการปลุกซ้ำ:
ทำงานเฉพาะที่เมื่อมีสัญญาณเตือน "งานในพื้นที่" หมายถึงอะไรก็ได้ ไม่มีการเข้าถึงเซิร์ฟเวอร์หรือต้องการข้อมูลจากเซิร์ฟเวอร์
และในขณะเดียวกัน ให้ตั้งเวลาปลุกที่มีคำขอจากเครือข่ายให้ ไฟที่ระยะเวลาแบบสุ่ม
รักษาความถี่ในการตั้งปลุกให้น้อยที่สุด
อย่าปลุกระบบอุปกรณ์โดยไม่จำเป็น (ลักษณะการทำงานนี้จะกำหนดโดย ประเภทการปลุก ตามที่อธิบายไว้ในเลือกประเภทการปลุก)
อย่าทำให้เวลาเรียกใช้การปลุกแม่นยำกว่าที่ควรจะเป็น
ใช้
setInexactRepeating()
แทนที่จะเป็นsetRepeating()
เมื่อคุณใช้setInexactRepeating()
Android ซิงค์ข้อมูลการปลุกซ้ำจากแอปหลายรายการและไฟไหม้ ได้ในเวลาเดียวกัน ซึ่งจะช่วยลดจำนวนครั้งทั้งหมดที่ระบบต้องปลุกระบบ อุปกรณ์จะช่วยลดการใช้แบตเตอรี่ สำหรับ Android 4.4 (API ระดับ 19) การปลุกซ้ำทั้งหมดเป็นการปลุกที่ไม่แน่นอน หมายเหตุ ขณะที่setInexactRepeating()
คือการปรับปรุงจากsetRepeating()
, แอปก็ยังคงทำให้เซิร์ฟเวอร์ทำงานหนักหากอินสแตนซ์ของแอปหนึ่งๆ ไปถึงเซิร์ฟเวอร์ ในเวลาเดียวกัน ดังนั้น สำหรับคำขอเครือข่าย ให้เพิ่มการสุ่มลงใน ตามที่คุณพูดถึงก่อนหน้านี้หลีกเลี่ยงการตั้งปลุกตามเวลาของนาฬิกาหากเป็นไปได้
การปลุกซ้ำที่ยึดตามเวลาทริกเกอร์ที่แม่นยำจะปรับขนาดได้ไม่ดีนัก ใช้
ELAPSED_REALTIME
หาก คุณสามารถทำได้ การปลุกแบบอื่น ซึ่งอธิบายไว้ในรายละเอียดเพิ่มเติมในส่วนต่อไปนี้