I want to create three Alarm named as Reminder1, Reminder2, Reminder3.
I know that, I can create multiple alarm for three of the above using different requestCode. Corresponding code was embedded below
private void startReminderAlarm(int id, Calendar from_date, long interval) {
// TODO Auto-generated method stub
Intent remIntent;
PendingIntent pendingIntent;
AlarmManager manager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
remIntent = new Intent(mContext, ReminderReceiver.class);
remIntent.putExtra("ID", id);
pendingIntent = PendingIntent.getBroadcast(mContext, id, remIntent, 0);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, from_date.getTimeInMillis(), interval, pendingIntent);
Toast.makeText(mContext, "Alarm Set for id" + id, Toast.LENGTH_SHORT).show();
Log.d(TAG, "Alarm Set for id: " + id);
}
Depending on the id of Reminder, I'm starting each alarm. This was working fine. My question is,
1) Reminder1 alarm to be set for daily morning.
2) Reminder2 to be set for Daily Twice.
3) Reminder3 to be set for Daily Thrice.
1st case, wont create a problem, because it shall be set only once with corresponding id.
2nd case, If I create two alarm with corresponding id, the last one only persists. First one will be discarded.
3rd case, If I create three alarm with corresponding id, the last one only persists. First and second will be discarded.
I want to create 2 or 3 separate alarms with particular id.
Please suggest me any solution to solve this.
Use intent.setData to distinguish the intents. That is
remIntent = new Intent(mContext, ReminderReceiver.class);
remIntent.putExtra("ID", id);
remIntent.setData(Uri.parse("reminder:"+id+"/"+from_date.getTimeInMillis()+"/"+interval));
Related
I'm working on an event planner for Android (learning purposes), and want each event to have it's own reminder. I've got the alarms working and they successfully trigger and know how to check if the alarms exist, but I'm unable to find out how to get the time for each alarm.
I've managed to identify if the alarm exists using:
Intent i = new Intent(getApplicationContext(), NotificationReceiver.class);
pIntent = PendingIntent.getBroadcast(getApplicationContext(), (int) id, i, PendingIntent.FLAG_NO_CREATE);
And I've tried using
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar test = Calendar.getInstance();
test.setTimeInMillis(am.getNextAlarmClock().getTriggerTime());
Log.d(TAG, "getReminder: TRIGGER: " + test.getTime());
But the time displayed there doesn't even match any of my alarms when testing. Also this doesn't allow me to identify which event the alarm belongs to anyway.
This is where I create the reminders.
public void makeReminder(String event, long reminder){
Log.d(TAG, "makeReminder: Started");
Intent i = new Intent (getApplicationContext(), NotificationReceiver.class);
i.putExtra("id", event); // eventID
i.putExtra("reminder", reminder); // reminderKey
i.putExtra("reminderTime", reminderCal.getTimeInMillis()); // actual time for the reminder
i.putExtra("message", "You have an upcoming event on " + dateTimeFormat.format(startCal.getTime()));
i.putExtra("name", eventName);
i.putExtra("channel", "event");
PendingIntent nIntent = (PendingIntent) PendingIntent.getBroadcast(
getApplicationContext(),
(int)reminder, i,
PendingIntent.FLAG_CANCEL_CURRENT
);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, reminderCal.getTimeInMillis(), nIntent);
Log.d(TAG, "makeReminder: reminder set for " + reminderCal.getTime());
Log.d(TAG, "makeReminder: reminderID: " + reminder);
}
I'm not sure how to proceed to get the time, but I'm hoping that it would be possible to get the triggertime with the reminderKey or alternatively fetching the reminderTime from the intent before the event actually gets triggered. The point is for users to see if there's an alarm set, when it is and then I know how to cancel or change the alarm. Just can't find a good way of displaying it.
Hopefully something that's simple to achieve, that I've overlooked :/ but can't seem to solve this.
You can't get this information from AlarmManager. If you need this information, you will need to save it in some persistent storage (SQLite database, SharedPreferences, File, etc.) and manage it yourself.
I've got a problem with the AlarmManager. I'm able to set up the Alarm with this code
private void setAlarm(long when) {
Intent intent = new Intent(NoteActivity.this, AlarmReceiver.class);
intent.putExtra("ID", note.getId());
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, PendingIntent.getBroadcast(NoteActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(getApplicationContext(),"Reminder set up", Toast.LENGTH_SHORT).show();
}
This code works well if I set long when = 5 * 1000; \\For example 5secs later, but if I use this code
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
long selectedDate = date.getTime();
long timeSince1970 = System.currentTimeMillis();
long timeForAlarm = selectedDate - timeSince1970;
Intent intent = new Intent(NoteActivity.this, AlarmReceiver.class);
intent.putExtra("ID", note.getId());
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeForAlarm, PendingIntent.getBroadcast(NoteActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(getApplicationContext(),"Reminder set for "+calendar.getTime().toString(), Toast.LENGTH_SHORT).show();
my alarm triggerd 2secs later. What I'm doing wrong? :/
I've tried AlarmManager.ELAPSED_REALTIME_WAKEUP and AlarmManager.RTC_WAKEUP but nothing changed.
Please do not check my question as duplicated. I didn't find something to try that solved my problem.
Assuming that you are working in Android Studio (if not - you must switch), click F1 while your text pointer is on set method and read description of AlarmManager::set.
Note: Beginning in API 19, the trigger time passed to this method is
treated as inexact: the alarm will not be delivered before this time,
but may be deferred and delivered some time later. The OS will use
this policy in order to "batch" alarms together across the entire
system, minimizing the number of times the device needs to "wake up"
and minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
Instead of set use setExact
manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeForAlarm, PendingIntent.getBroadcast(NoteActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
i used below code to create alarm.
public static void RegisterForAlarmEvent(Context ct, long intervel)
{
Intent intent = new Intent(ct, AlarmReceiver.class);
PendingIntent mAlarmSender = PendingIntent.getBroadcast(ct,
constants.ALARM_ID, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager am = (AlarmManager) ct
.getSystemService(ct.ALARM_SERVICE);
Long totalTime = getCurrentTimeinMiliSeconds() + intervel;
am.set(AlarmManager.RTC, totalTime , mAlarmSender);
}
I need to check next time, if the alarm is already registered & its triggered. If its triggered then only i need to re-register.
So, i'm checking like this to know, if the alaram is already registered.
boolean alarmUp = (PendingIntent.getBroadcast(ct, id, intent, PendingIntent.FLAG_NO_CREATE)!= null);
If i call register using alaramevent method & check alarm is already registered i get NULL, literally it should return NULL, once the alarm is executed right?
How to check alarm is already fired or not?
According to docs FLAG_NO_CREATE:
Flag for use with getActivity, getBroadcast, and getService: if the described PendingIntent does not already exist, then simply return null instead of creating it.
So if the pending intent already created then it will return the reference to the previous pending intent. If not then it will return null.
And the answer to your question is maintain some shared preference value and change that value in broadcast receiver. Based on that value
So I need to create a certain number of alarms. If the user needs 10 alarms at regular intervals throughout the day, how can I efficiently write my code so that I make 10 alarms?
Or, is it possible to overwrite a single alarm multiple times?
This is in regards to Android App Dev.
Is the choice of number of alarms left to the user?
If yes,
Make a user interface (in your activity) for the user itself to add
new alarm or give the number of alarms.
Declare an Alarm and instantiate a new object for each user request while maintaining the total number of alarms and change all the time for each accordingly.
// context variable contains your `Context`
AlarmManager mgrAlarm = (AlarmManager) context.getSystemService(ALARM_SERVICE);
ArrayList<PendingIntent> intentArray = new ArrayList<PendingIntent>();
int[] TimeForAlarm = new int[UserInput];
// Set the time for each alarm according to your need and UserInput.
for(i = 0; i < UserInput; ++i)
{
Intent intent = new Intent(context, OnAlarmReceiver.class);
// Loop counter `i` is used as a `requestCode`
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent, 0);
// Single alarms according to time we have in TimeForAlarm.
mgrAlarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
TimeForAlarm[i],
pendingIntent);
intentArray.add(pendingIntent);
}
This will create 'UserInput' number of alarms as times according to TimeForAlarm array.
At the end intentArray will have all the pending intents (if you need them).
Take the number from user, and make a method
setAlaram(int numOfMeals){
} and you can use your formula with this number to set the alarams !
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?
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.
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.
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.
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);
}
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())
}
}
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.
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);