หมายเหตุ: ฉันลองใช้วิธีแก้ไขปัญหาต่าง ๆ ที่เขียนเกี่ยวกับที่นี่ใน StackOverflow (ตัวอย่างที่นี่ ) โปรดอย่าปิดสิ่งนี้โดยไม่ตรวจสอบว่าโซลูชันของคุณจากสิ่งที่คุณพบว่าทำงานได้โดยใช้แบบทดสอบที่ฉันเขียนด้านล่าง
พื้นหลัง
มีความต้องการในแอพที่ผู้ใช้ตั้งเตือนเพื่อกำหนดเวลาในเวลาที่กำหนดดังนั้นเมื่อแอพได้รับการทริกเกอร์ในเวลานี้มันจะทำสิ่งเล็ก ๆ ในพื้นหลัง (เพียงการดำเนินการแบบสอบถาม DB) และแสดง การแจ้งเตือนง่าย ๆ ที่จะบอกเกี่ยวกับการแจ้งเตือน
ในอดีตที่ผ่านมาฉันใช้รหัสง่าย ๆ เพื่อกำหนดสิ่งที่จะกำหนดเวลาค่อนข้างเฉพาะ:
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val pendingIntent = PendingIntent.getBroadcast(context, requestId, Intent(context, AlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
when {
VERSION.SDK_INT >= VERSION_CODES.KITKAT -> alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
else -> alarmManager.set(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
}
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("AppLog", "AlarmReceiver onReceive")
//do something in the real app
}
}
การใช้งาน:
val timeToTrigger = System.currentTimeMillis() + java.util.concurrent.TimeUnit.MINUTES.toMillis(1)
setAlarm(this, timeToTrigger, 1)
ปัญหา
ตอนนี้ฉันได้ทดสอบโค้ดนี้เกี่ยวกับอีมูเลเตอร์ใน Android รุ่นใหม่และใน Pixel 4 กับ Android 10 และดูเหมือนว่าจะไม่เปิดใช้งานหรือบางทีมันจะเริ่มทำงานหลังจากผ่านไปนานมากเนื่องจากสิ่งที่ฉันให้มา ฉันตระหนักดีถึงพฤติกรรมที่แย่มากที่ผู้ผลิต OEM บางรายเพิ่มเพื่อลบแอพออกจากงานล่าสุด แต่อันนี้มีทั้งตัวเลียนแบบและอุปกรณ์พิกเซล 4 (สต็อค)
ฉันได้อ่านเอกสารเกี่ยวกับการตั้งค่าการเตือนว่ามันถูก จำกัด สำหรับแอพเพื่อที่จะไม่เกิดขึ้นบ่อยเกินไป แต่สิ่งนี้ไม่ได้อธิบายวิธีตั้งค่าการเตือนในเวลาที่กำหนดและมันไม่ได้อธิบายแอป Clock ของ Googleมาได้อย่างไร
ไม่เพียงแค่นั้น แต่ตามสิ่งที่ฉันเข้าใจมันบอกว่าควรใช้ข้อ จำกัด โดยเฉพาะอย่างยิ่งสำหรับสถานะพลังงานต่ำของอุปกรณ์ แต่ในกรณีของฉันฉันไม่มีสถานะนี้ทั้งอุปกรณ์และตัวเลียนแบบ ฉันตั้งค่าการเตือนที่จะถูกเรียกใช้ในอีกประมาณหนึ่งนาทีจากนี้
เมื่อเห็นว่าแอพนาฬิกาปลุกจำนวนมากไม่ทำงานอีกต่อไปเหมือนที่เคยเป็นมาฉันคิดว่ามีบางอย่างที่ขาดหายไปจากเอกสาร ตัวอย่างของแอพดังกล่าวเป็นแอพTimelyยอดนิยมที่ซื้อโดย Googleแต่ไม่เคยได้รับการอัพเดตใหม่เพื่อจัดการข้อ จำกัด ใหม่และตอนนี้ผู้ใช้ต้องการกลับคืนมา . แต่บางปพลิเคชันที่นิยมทำผลงานได้ดีเช่นนี้
สิ่งที่ฉันได้ลอง
เพื่อทดสอบว่าสัญญาณเตือนทำงานได้จริงฉันทำการทดสอบเหล่านี้เมื่อพยายามเรียกใช้สัญญาณเตือนในไม่กี่นาทีนับจากนี้หลังจากติดตั้งแอปเป็นครั้งแรกทั้งหมดในขณะที่อุปกรณ์เชื่อมต่อกับพีซี (เพื่อดูบันทึก):
- ทดสอบเมื่อแอปอยู่เบื้องหน้าผู้ใช้จะมองเห็นได้ - ใช้เวลา 1-2 นาที
- ทดสอบเมื่อแอปถูกส่งไปที่พื้นหลัง (เช่นใช้ปุ่มหน้าแรก) - ใช้เวลาประมาณ 1 นาที
- ทดสอบเมื่องานของแอพถูกลบออกจากงานล่าสุด - ฉันรอนานกว่า 20 นาทีและไม่เห็นสัญญาณเตือนที่กำลังถูกทริกเกอร์เขียนลงในบันทึก
- เช่น # 3 แต่ยังปิดหน้าจอ มันอาจจะเลวร้ายยิ่ง ...
ฉันพยายามใช้สิ่งต่อไปทุกอย่างใช้งานไม่ได้:
alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(timeToTrigger, pendingIntent), pendingIntent)
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
การรวมกันของใด ๆ ข้างต้นด้วย:
if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) alarmManager.setWindow(AlarmManager.RTC_WAKEUP, 0, 60 * 1000L, pendingIntent)
พยายามใช้บริการแทน BroadcastReceiver ยังลองในกระบวนการที่แตกต่างกัน
พยายามทำให้แอพพลิเคชั่นถูกเพิกเฉยจากการปรับแต่งแบตเตอรี (ไม่ได้ช่วย) แต่เนื่องจากแอพอื่นไม่ต้องการมันฉันไม่ควรใช้มัน
พยายามใช้สิ่งนี้:
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP)
alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(timeToTrigger, pendingIntent), pendingIntent)
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, timeToTrigger, pendingIntent)
- พยายามมีบริการที่จะเรียกonTaskRemovedเพื่อกำหนดเวลาปลุกที่นั่นอีกครั้ง แต่สิ่งนี้ก็ไม่ได้ช่วย (บริการทำงานได้ดีแม้ว่า)
สำหรับแอพ Clock ของ Google ฉันไม่เห็นอะไรเป็นพิเศษเกี่ยวกับมันยกเว้นว่ามันจะแสดงการแจ้งเตือนก่อนที่จะถูกทริกเกอร์และฉันยังไม่เห็นมันในส่วน "ไม่เหมาะ" ในหน้าจอการตั้งค่าการเพิ่มประสิทธิภาพแบตเตอรี่
เมื่อเห็นว่านี่เป็นข้อผิดพลาดฉันได้รายงานเกี่ยวกับเรื่องนี้ที่นี่รวมถึงโครงการตัวอย่างและวิดีโอเพื่อแสดงปัญหา
ฉันตรวจสอบอีมูเลเตอร์หลายเวอร์ชันแล้วและดูเหมือนว่าพฤติกรรมนี้เริ่มต้นจาก API 27 (Android 8.1 - Oreo) ดูเอกสารฉันไม่เห็น AlarmManager ถูกกล่าวถึง แต่มันเขียนเกี่ยวกับการทำงานพื้นหลังต่างๆ
คำถาม
เราจะตั้งค่าบางสิ่งให้ทำงานในเวลาที่แน่นอนในทุกวันนี้ได้อย่างไร
ทำไมวิธีการแก้ปัญหาข้างต้นไม่ทำงานอีกต่อไป? ฉันไม่มีอะไรเลยหรือ ได้รับอนุญาต? บางทีฉันควรจะใช้คนงานแทน? แต่มันก็ไม่ได้หมายความว่ามันจะไม่ตรงเวลาเลยเหรอ?
แอพ "นาฬิกา" ของ Google เอาชนะสิ่งเหล่านี้ทั้งหมดได้อย่างไรและเรียกใช้ในเวลาที่แน่นอนเสมอแม้ว่าจะถูกเรียกใช้เมื่อไม่กี่นาทีที่ผ่านมา เป็นเพราะแอประบบหรือไม่ จะเกิดอะไรขึ้นถ้ามันได้รับการติดตั้งเป็นแอพผู้ใช้บนอุปกรณ์ที่ไม่มีมันในตัว?
หากคุณบอกว่าเป็นเพราะแอประบบฉันพบแอปอื่นที่สามารถส่งสัญญาณเตือนได้สองครั้งใน 2 นาทีที่นี่ถึงแม้ว่าฉันคิดว่ามันอาจใช้บริการเบื้องหน้าในบางครั้ง
แก้ไข: ทำพื้นที่เก็บข้อมูล Github เล็ก ๆ ที่จะลองคิดอยู่ที่นี่
แก้ไข: ในที่สุดก็พบตัวอย่างที่มีทั้งแบบเปิดและไม่มีปัญหานี้ น่าเศร้าที่มันซับซ้อนมากและฉันยังคงพยายามหาสิ่งที่ทำให้มันแตกต่างกันมาก (และรหัสขั้นต่ำที่ฉันควรเพิ่มใน POC ของฉัน) คืออะไรที่ทำให้สัญญาณเตือนของมันยังคงอยู่หลังจากที่ลบแอพออกจากงานล่าสุด