Android Daily Repeating Alarm/Reminder at Specific Time With AlarmManager

This example demonstrate daily alarm at specific time (e.g. 8.30am daily).

  • Read about Caveats of Repeating Alarm.
  • Use setExact / setWindow / set to start alarm at exact timing (or setExactAndAllowWhileIdle for extreme accuracy), then set alarm again at onReceive for the next day. Don't use setInexactRepeating or setRepeating due to time drift and inability to guarantee execution at exact time.
class ReminderReceiver : BroadcastReceiver() {    companion object {        private const val REQUEST_TIMER1 = 1        private const val PARAM_NAME = "name"        fun startAlarm(context: Context, startMillis: Long? = null) {            val pendingIntent = getIntent(context, REQUEST_TIMER1, "Alarm at 8.30am")            val alarm = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager            // trigger at 8:30am            val alarmTime = LocalTime.of(8, 30)            var now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)            val nowTime = now.toLocalTime()            // if same time, schedule for next day as well            // if today's time had passed, schedule for next day            if (nowTime == alarmTime || nowTime.isAfter(alarmTime)) {                now = now.plusDays(1)            }            now = now.withHour(alarmTime.hour).withMinute(alarmTime.minute) // .withSecond(alarmTime.second).withNano(alarmTime.nano)            // alarm use UTC/GMT time            val utc = now.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()            val startMillis = utc.atZone(ZoneOffset.UTC)!!.toInstant()!!.toEpochMilli()            Timber.d("Alarm will trigger in ${(startMillis-System.currentTimeMillis())/1000}s")            // AlarmManagerCompat.setExact(alarm, AlarmManager.RTC_WAKEUP, startMillis, pendingIntent!!)            if (Build.VERSION.SDK_INT >= 19) {                // alarm.setExact(AlarmManager.RTC_WAKEUP, startMillis, pendingIntent)                // effort to save battery, allow deviation of 15 minutes                val windowMillis = 15L * 60L * 1_000L                alarm.setWindow(AlarmManager.RTC_WAKEUP, startMillis, windowMillis, pendingIntent)            }            else {                alarm.set(AlarmManager.RTC_WAKEUP, startMillis, pendingIntent)            }        }        fun cancelAlarm(context: Context) {            val pendingIntent = getIntent(context, REQUEST_TIMER1)            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager            alarmManager.cancel(pendingIntent)        }    }    override fun onReceive(context: Context, intent: Intent) {        try {            val name = intent.getStringExtra(PARAM_NAME)            Timber.d("onReceive, name=$name")            Toast.makeText(context, name, Toast.LENGTH_LONG).show()        }        catch (e: Exception) {            Timber.e(e)        }        finally { // use try/catch to make sure next day alarm is set even if exception happens            // start alarm for next day            startAlarm(context)        }    }}

Edit AndroidManifest.xml.

```xml
<manifest ..>
    <application ...>
        <receiver android:name=".ReminderReceiver" />
    </application>
</manifest>

Usage

ReminderReceiver.startAlarm(context)

NOTE: The AlarmManager won't survive a device reboot. You have to implement a device bootup receiver and call ReminderReceiver.startAlarm(context).

NOTE: Refer Setup Android Notification.

NOTE: To support multiple alarm, use a different requestCode for each alarm. Refer Android AlarmManager: Multiple Alarm With Arguments/Parameters.

NOTE: AlarmManager is removed when the app is uninstalled, and it seems the Alarm is cancelled after APK update (not sure if this is true or always true).

You might want to explore Android Schedule Daily Repeating/Reminder Alarm at Specific Time With WorkManager.

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.