How to set multiple alarms using alarm manager in android

AndroidAlarmmanager

Android Problem Overview


I'm building an alarm application. I have successfully implemented basic alarm functions.

Calendar calendar = Calendar.getInstance();
calendar.set(calendar.HOUR_OF_DAY, sHour);
calendar.set(calendar.MINUTE, sMin);
calendar.set(calendar.SECOND, 0);
calendar.set(calendar.MILLISECOND, 0);
long sdl = calendar.getTimeInMillis();

Intent intent = new Intent(AlarmList.this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmList.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager ALARM1 = (AlarmManager)getSystemService(ALARM_SERVICE);
ALARM1.set(AlarmManager.RTC_WAKEUP, sdl, sender);

In my application, user can select days (sunday,monday...) to repeat the alarm weekly. I'm trying to create multiple alarms to repeat weekly but don't know how to do it. Can I create it using (repeat) interval or should I create multiple alarm managers?

Android Solutions


Solution 1 - Android

You need to use different Broadcast id's for the pending intents. Something like this:

Intent intent = new Intent(load.this, AlarmReceiver.class);
final int id = (int) System.currentTimeMillis();
PendingIntent appIntent = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_ONE_SHOT);

Using the system time should be a unique identifier for every pending intent you fire.

Solution 2 - Android

From http://developer.android.com/reference/android/app/AlarmManager.html">the docs: > If there is already an alarm for this Intent scheduled (with the > equality of two intents being defined by http://developer.android.com/reference/android/content/Intent.html#filterEquals(android.content.Intent)">filterEquals(Intent)</a>;, then > it will be removed and replaced by this one

Multiple AlarmManagers would not resolve your issue. If they have multiple different alarms (different times and different days), then you would need to set the alarm within the BroadcastReceiver every time you fire off a previous alarm.

You would also need to hold http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_BOOT_COMPLETED">`RECEIVE_BOOT_COMPLETED`</a> and have a BroadcastReceiver to receive the boot so that if the phone is rebooted you can re-schedule your alarms.

Solution 3 - Android

To set multiple alarms you need to define your Intent each time so that it is distinguishable from the others. The easiest way I find to do this is to set the data field of your Intent something as follows:

// give your alarm an id and save it somewhere
// in case you want to cancel it in future
String myAlarmId = ...;

// create your Intent
Intent intent = new Intent(AlarmList.this, AlarmReceiver.class);
intent.setData(Uri.parse("myalarms://" + myAlarmId));
...

The rest of your code @Hassy31 is fine as is and remains unchanged.

Note that the requestCode parameter in the PendingIntent.getBroadcast() method (as suggested by @parag) is unused according to the documentation so this ain't the right way to go about it.

Solution 4 - Android

set Broadcast id for pendingIntent

for (int id = 0; id < 3; id++) {
        // Define pendingintent
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id,ntent, 0); 
        // set() schedules an alarm 
        alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
}

Solution 5 - Android

Set multiple alarms using android alarm manager

//RC_ARRAY is store all the code that generate when alarm is set 
private lateinit var RC_ARRAY:ArrayList<Int>
//tick is just hold the request when new alarm set
private var tick :Int=0

//setAlarm method set alarm
fun setAlarm(c: Calendar, context: Context) {
    val manager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

//when alarm store set the request assign to tick variable
    tick = System.currentTimeMillis().toInt()
//Add all the alarm Request into RC_ARRAY for just cancel the alarm
    RC_ARRAY.add(tick)

//Notification Broadcast intent
    val intentAlarm = Intent(context, AlaramFireReceiver::class.java).let {
        PendingIntent.getBroadcast(context, tick, it, PendingIntent.FLAG_ONE_SHOT)
    }


//alarm fire next day if this condition is not statisfied 
    if (c.before(Calendar.getInstance())) {
        c.add(Calendar.DATE, 1)
    }
//set alarm
    manager.setExact(AlarmManager.RTC_WAKEUP, c.timeInMillis, intentAlarm)


}
//remove specific alarm
private fun removeAlarm(context: Context) {
    val manager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    //remove specific alarm according to alarm request code
    for (i in RC_ARRAY){
        val intentAlarm = Intent(context, AlaramFireReceiver::class.java).let {
            PendingIntent.getBroadcast(context, i, it, 0)
        }
//cancel alarm
        manager.cancel(intentAlarm)
    }
}



//delivers notification for alarm
class AlaramFireReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
//Notification ID
       val channelid="channelId"
        val manger=context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
//check for device only available for Oreo and above  
        if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.O){
            val channel= NotificationChannel(channelid,"alarm notification",NotificationManager.IMPORTANCE_HIGH)
            channel.enableLights(true)
            manger.createNotificationChannel(channel)
        }
//build notification
        val build=NotificationCompat.Builder(context,channelid)
            .setSmallIcon(R.drawable.ic_access_time_black_24dp)
            .setContentTitle("alarm")
            .setContentTitle("time done")
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setColor(Color.RED)
//Deliver notification 
        manger.notify(0,build.build())
    }
}

Solution 6 - Android

What I do is something similar to how you move to the next element in a linked list. I keep in database a ReminderEntity that has all the days of the week the user enabled the Alarm to go off. Then I schedule the first day only. When the first day triggers then in that moment I schedule the next day and so on. Same thing if the user deletes the first coming Alarm before it happens. In this case I clear the removed day from the entity and schedule an alarm for the next one available.

Solution 7 - Android

use different requestCode for the pending intents and use .FLAG_MUTABLE for type of Flag

int requestCode = (int) System.currentTimeMillis();
Intent intent = new Intent(load.this, AlarmReceiver.class);
return PendingIntent.getBroadcast(this, requestCode , intent, PendingIntent.FLAG_MUTABLE);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHassy31View Question on Stackoverflow
Solution 1 - AndroidParag ChauhanView Answer on Stackoverflow
Solution 2 - AndroidReedView Answer on Stackoverflow
Solution 3 - AndroidAdil HussainView Answer on Stackoverflow
Solution 4 - AndroidHuệ NguyễnView Answer on Stackoverflow
Solution 5 - Androidamir khanView Answer on Stackoverflow
Solution 6 - AndroidPablo ValdesView Answer on Stackoverflow
Solution 7 - AndroidMark NashatView Answer on Stackoverflow