简体   繁体   中英

Android AlarmManager Only Works Once

I'm trying to reset a specific value in my app everyday at 11:59 PM. This is the code that I have for that:

val cal: Calendar = Calendar.getInstance()
cal[Calendar.HOUR_OF_DAY] = 23
cal[Calendar.MINUTE] = 59
cal[Calendar.SECOND] = 59
cal[Calendar.MILLISECOND] = 0
val pi: PendingIntent = PendingIntent.getBroadcast(
    applicationContext,
    0,
    Intent(this, DailyBroadcastReceiver::class.java),
    PendingIntent.FLAG_UPDATE_CURRENT
)
val am: AlarmManager = this.getSystemService(ALARM_SERVICE) as AlarmManager
am.setRepeating(
    AlarmManager.RTC_WAKEUP,
    cal.timeInMillis,
    AlarmManager.INTERVAL_DAY,
    pi
)

Problem is it only works once. After that, it doesn't keep resetting the value I gave in my DailyBroadcastReceiver . How do I fix this so that AlarmManager is triggered daily?

Since API 19 repeating alarms have never been exact and if you want an exact time, you have to use exact single time alarms that reset themselves.

You will likely need to use setExactAndAllowWhileIdle() as chances are high that at that time, the device has gone into Doze mode.

However, be sure to check out the best practices when dealing with these sorts of things as the reason behind a lot of the issues with AlarmManager and other scheduled tasks is due to battery saving measures that have gone in place to curb bad behaving apps. Ensure that the user is aware of potential battery drain, though in this case if all you are doing is resetting a value once per day, I can't imagine any significant battery drain from this.

The last thing is that with AlarmManager, you will need to reschedule the alarms on boot which means you will need to add this to you manifest

<application>
    <!-- ... -->
    <receiver android:name="RECEIVER_NAME">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> this action is sent before the user unlocks their device-->
        </intent-filter>
    </receiver>
    <!-- ... -->
</application>

And make an additional Broadcast receiver (or use the same one and compare intent.action to Intent.ACTION_BOOT_COMPLETED to determine if it is being triggered because of a reboot or if the alarm was triggered)

Also, add any additional details (Target API level, how you are testing, what device you are testing on, the API level of the device you are testing on) if changing to exact single time alarms doesn't fix the issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM