Schedule Task Using Alarm Manager Android

In this lesson, on android alarm manager we will see how a alarm manager works.

Let us go thorough alarm manager in now in general we know that alarm is a task of making us know that a particular time has arrived to do any task like early in the morning to wake up and so on..

Android alarm manager

In the same way we will provide our program with alarm manager to let it know when to do a task by scheduling it.When ever we have to do any background task in android latest versions due to doze mode we can’t achieve it easily.

We have four ways in alarm manager usage

Here is the list of types:

  • ELAPSED_REALTIME—Fires the pending intent based on the amount of time since the device was booted, but doesn't wake up the device. The elapsed time includes any time during which the device was asleep.
  • ELAPSED_REALTIME_WAKEUP—Wakes up the device and fires the pending intent after the specified length of time has elapsed since device boot.
  • RTC—Fires the pending intent at the specified time but does not wake up the device.
  • RTC_WAKEUP—Wakes up the device to fire the pending intent at the specified time.

Create a alarm notification receiver class extending broadcast class so as to receive the alarm and perform a task on background.

class ReminderBroadcast : BroadcastReceiver()

Inside on onReceive class make your declarations to be done i.e., task to be performed when alarm goes off.

override fun onReceive(context: Context, intent: Intent) {}

Now we will add a notification task for on Receive

private fun showNotification(context: Context, title: String, message: String) {
val mNotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"1",
"CH_ID",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "Example Alarm"
mNotificationManager.createNotificationChannel(channel)
}
val mBuilder = NotificationCompat.Builder(context, "1")
.setSmallIcon(R.mipmap.ic_launcher) // notification icon
.setContentTitle(title) // title for notification
.setContentText(message) // message for notification
.setAutoCancel(true) // clear notification after click
val intent = Intent(context, MainActivity::class.java)
val pi = PendingIntent.getActivity(context, 0, intent, 0)
mBuilder.setContentIntent(pi)
mNotificationManager.notify(1001, mBuilder.build())
}

You may have your own declarations i am using a notification here as a example.

ReminderBroadcast.kt

class ReminderBroadcast : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {

showNotification(
context,
"Reminder 1",
"This is the example reminder 1 from alarm manager"
)
}

private fun showNotification(context: Context, title: String, message: String) {
val mNotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"1",
"CH_ID",
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = "Example Alarm"
mNotificationManager.createNotificationChannel(channel)
}
val mBuilder = NotificationCompat.Builder(context, "1")
.setSmallIcon(R.mipmap.ic_launcher) // notification icon
.setContentTitle(title) // title for notification
.setContentText(message) // message for notification
.setAutoCancel(true) // clear notification after click
val intent = Intent(context, MainActivity::class.java)
val pi = PendingIntent.getActivity(context, 0, intent, 0)
mBuilder.setContentIntent(pi)
mNotificationManager.notify(1001, mBuilder.build())
}
}

To create alarm manager in your activity

val alarmManager= getSystemService(Context.ALARM_SERVICE) as AlarmManager

then intent and pending intent to handle the task

val intent = Intent(appContext, ReminderBroadcast::class.java)
intent.putExtra("ARG_REQUEST_CODE_KEY", 11)
val pendingIntent = PendingIntent.getBroadcast(appContext, 11, intent, PendingIntent.FLAG_UPDATE_CURRENT)

set the alarm


val alarmStartTime = Calendar.getInstance()
alarmStartTime.timeInMillis = System.currentTimeMillis()
alarmStartTime[Calendar.HOUR_OF_DAY] = 4
alarmStartTime[Calendar.MINUTE] = 37
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
alarmStartTime.timeInMillis, AlarmManager.INTERVAL_DAY, pendingIntent
)

schedule Notification alarm in activity

Here are some examples of using RTC_WAKEUP.

Wake up the device to fire the alarm at approximately 4:37 a.m., and repeat once a day at the same time:

private fun scheduleNotification() {
val intent = Intent(this@MainActivity, ReminderBroadcast::class.java)
intent.putExtra("ARG_REQUEST_CODE_KEY", 11)
val pendingIntent = PendingIntent.getBroadcast(this@MainActivity, 11, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val alarmStartTime = Calendar.getInstance()
alarmStartTime.timeInMillis = System.currentTimeMillis()
alarmStartTime[Calendar.HOUR_OF_DAY] = 4
alarmStartTime[Calendar.MINUTE] = 37
alarmManager!!.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
alarmStartTime.timeInMillis, AlarmManager.INTERVAL_DAY, pendingIntent
)
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

private var alarmManager: AlarmManager? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
scheduleNotification();
}

private fun scheduleNotification() {
val intent = Intent(this@MainActivity, ReminderBroadcast::class.java)
intent.putExtra("ARG_REQUEST_CODE_KEY", 11)
val pendingIntent = PendingIntent.getBroadcast(this@MainActivity, 11, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val alarmStartTime = Calendar.getInstance()
alarmStartTime.timeInMillis = System.currentTimeMillis()
alarmStartTime[Calendar.HOUR_OF_DAY] = 4
alarmStartTime[Calendar.MINUTE] = 37
alarmManager!!.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
alarmStartTime.timeInMillis, AlarmManager.INTERVAL_DAY, pendingIntent
)
}
}

in Manifests.xml register reciever

<application..>    //...
<receiver
android:name=".ReminderBroadcast"
android:enabled="true"
android:exported="false" />

</application>

Cancel an alarm

Depending on your app, you may want to include the ability to cancel the alarm. To cancel an alarm, call cancel() on the Alarm Manager, passing in the PendingIntent you no longer want to fire. For example:

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

Impacts of Doze and App Standby

Doze and App Standby were introduced in Android 6.0 (API level 23) in an effort to extend device battery life. When the device is in Doze mode any standard alarms will be deferred until the device exits Doze mode or a maintenance window opens. If you must have an alarm fire even in Doze mode you can use either setAndAllowWhileIdle() or setExactAndAllowWhileIdle(). Your app will enter App Standby mode when it is idle, meaning the user has not used it for a period of time and the app does not have a foreground process. When the app is in App Standby alarms are deferred just like in Doze mode. This restriction is lifted when the app is no longer idle or if the device is plugged in to a power supply. For more information on how your app is impacted by these modes, read Optimizing for Doze and App Standby.

Android Developer Passionate about Clean Code, Open Source, Mobile UX, and coffee.