Reputation: 2813
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?
Upvotes: 64
Views: 70009
Reputation: 768
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);
Upvotes: 0
Reputation: 35986
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.
Upvotes: 177
Reputation: 984
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.
Upvotes: 0
Reputation: 2696
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())
}
}
Upvotes: 1
Reputation: 21
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);
}
Upvotes: 2
Reputation: 32221
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.
Upvotes: 7
Reputation: 14984
From the docs:
If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by filterEquals(Intent), 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 RECEIVE_BOOT_COMPLETED
and have a BroadcastReceiver
to receive the boot so that if the phone is rebooted you can re-schedule your alarms.
Upvotes: 11