I am setting Alarm using Alarm Manager And setting this Alarm By Picking Values from SQlite Database.The Alarm is working fine for future Alarms but the problem is when I open the Activity in which Alarm Function is Called, The Alarm Start ringing for All Previous Times. How Should I solve this problem ?
Here is My Alarm Function
void Alaramset()
{
Cursor cursor=mydb.getAllData();
if (cursor.moveToFirst())
{
do{
String alarm1 = cursor.getString (cursor.getColumnIndex(DBHelper.ALARM_COLUMN_REMINDER1));
int id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(DBHelper.ALARM_COLUMN_ID)));
int minute=Integer.parseInt (alarm1.substring(3, 5));
int hr=Integer.parseInt(alarm1.substring(0, 2));
Intent myIntent = new Intent(getActivity(), MyAlaramService.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
PendingIntent pendingIntent = PendingIntent.getService(getActivity(), id, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getActivity().getSystemService(Context.ALARM_SERVICE);
// Toast.makeText(getActivity(), ""+minute+" : "+hr, 300).show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hr);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
while (cursor.moveToNext());
}
}
It looks like you are scheduling alarms that happen in the past.
Any alarm scheduled in the past will trigger immediately.
A simple solution would be to schedule past alarms for the next day.
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if (calendar.before(now) {
// alarm has already happened. schedule it for tomorrow
calendar.add(Calendar.Date, 1);
}
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
My application creates an alarm that repeats every day. Since it is not possible to know if an alarm is already registered, I create the alarm every time the application is launched.
Here is the function that is called at the beginning of the main activity (inside onCreate()):
public static void setAlarm(Context context) {
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
Calendar currentCal = (Calendar)firingCal.clone();
Random rnd = new Random();
// Each day between 1:00 AM and 1:30 AM (some jitter added)
firingCal.set(Calendar.HOUR_OF_DAY, 1);
firingCal.set(Calendar.MINUTE, rnd.nextInt(30));
firingCal.set(Calendar.SECOND, 0);
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) {
//set from today
alarmManager.setInexactRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
//set from next day
firingCal.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = firingCal.getTimeInMillis();
alarmManager.setInexactRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
Is it OK to recreate the alarm each time the application is launched? Should I use some flags on the PendingIntent (like update or cancel existing PendingIntent)?
Thanks!
Update: is it a problem if I use flag 0 instead of PendingIntent.FLAG_UPDATE_CURRENT from a performance perspective?
Newbie here, I have this function setAlarm:
public void setAlarm(){
SharedPreferences sa=PreferenceManager.getDefaultSharedPreferences(getBaseContext());
int hr=sa.getInt("alarmhour", 6);
int mn=sa.getInt("alarmminute", 0);
String st1=sa.getString("alarmstatus", "Alarm Disabled");
if(st1.equals("Alarm Enabled"))
{
AlarmManager ala = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent inte = new Intent(this, epicalarm.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, inte, 0);
Calendar time = Calendar.getInstance();
time.set(Calendar.HOUR_OF_DAY, hr);
time.set(Calendar.MINUTE, mn);
time.set(Calendar.SECOND, 0);
ala.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);
}
}
Each time I call the function setAlarm , the onReceive method gets called and displays the alarm . Why?
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, h);
calendar.set(Calendar.MINUTE, m);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND,0);
// if values of h and m are less than current time
//then 'if' block will executes and adds the amount of days as 1 to your calendar object.
if (calendar.before(Calendar.getInstance()))
{
calendar.add(Calendar.DATE, 1);
}
//you will get an alarm` after a day instead of now
ala.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
The second parameter in
ala.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);
is to specify when to trigger the alarm first. In your code, you are triggering it for the time you read from your shared preferences. If that time has already elapsed, the alarm gets triggered immediately. That may be one reason why the onReceive() method gets called.
Check if the time you read is some time in the future.
I have a notification at a specific time, see my code:
//Create alarm manager
AlarmManager alarmMgr0 = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create pending intent & register it to your alarm notifier class
Intent intent0 = new Intent(this, AlarmReceiver_maandag_1e.class);
intent0.putExtra("uur", "1e");
PendingIntent pendingIntent0 = PendingIntent.getBroadcast(this, 0, intent0, 0);
//set timer you want alarm to work (here I have set it to 8.30)
Calendar timeOff9 = Calendar.getInstance();
timeOff9.set(Calendar.HOUR_OF_DAY, 8);
timeOff9.set(Calendar.MINUTE, 30);
timeOff9.set(Calendar.SECOND, 0);
//set that timer as a RTC Wakeup to alarm manager object
alarmMgr0.set(AlarmManager.RTC_WAKEUP, timeOff9.getTimeInMillis(), pendingIntent0);
This works perfect except one thing.
The notification is set for 8:30 with an alarm manager
If I launch the app after 8:30, 9:00 for example, the notification still shows..
Is there a possibility that the alarm goes off at 8:30 but not later?
Edit
For anyone having the same problem, here is the solution:
Put this in your broadcastreceiver:
long current_time = System.currentTimeMillis();
Calendar timeOff9 = Calendar.getInstance();
timeOff9.set(Calendar.HOUR_OF_DAY, 8);
timeOff9.set(Calendar.MINUTE, 35);
timeOff9.set(Calendar.SECOND, 0);
long limit_time = timeOff9.getTimeInMillis();
if (current_time > limit_time) {
//nothing
} else {
//show notification
}
You can also try this method of Alarm Manager:
public void setExact (int type, long triggerAtMillis, PendingIntent operation)
But it requiers API level 19.
Ok, let me modify the question and make it much easier. I Hope you'll be able to get me the solution for this. Both the alarms should be scheduled simultaneously, which is not happening here. I am even using unique requestcode for the pending intent. HELP ME please.....
//On click Listener
private OnClickListener mOneShotListener = new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
//I even tried sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, PendinIntent.FLAG_UPDATE_CURRENT);
//the alarm to go off 30 seconds from now.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
//adds 2 minutes to the time
calendar.add(Calendar.MINUTE, 2);
sender = PendingIntent.getBroadcast(AlarmController.this,1, intent,0);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender2);
}
};
OLD Question:
I want to set two alarms at the same time for two different operations to be performed.
For Eg. A user sets alarm at 2'O clock and sets the duration to 15 mins. The first alarm should fire at 2'O clock which performs function1 and the second alarm should fire at 2:15 as the user specified the duration as 15 mins which performs the function2. This operation should be repeated everyday at 2'O clock unless the user changes the time.
I am calling this both functions on button click:
On Click Event
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
..........
..........
new ReminderManager(this).setReminder(mRowId, mCalendar);
new ReminderManager(this).wakeReminder(mRowId, mCalendar, duration);
}
}
The setReminder contains
//sets alarm at 2'O clock
public void setReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext,(int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
The wakeReminder contains
//adds duration i.e. 15mins
public void wakeReminder(Long taskId, Calendar when, String duration){
Intent i = new Intent(mContext, OnAlarmReceiverWake.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
Long d = Long.parseLong(duration);
Long mins = d*60*100;
Long milli = when.getTimeInMillis() + mins;
PendingIntent pi = PendingIntent.getBroadcast(mContext, (int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi);
}
I have noticed that whenever mAlarmManager.set(); is executed successfully the LogCat shows notification like
"enqueueToast pkg=com.jellboi.android.togglemode callback=android.app ITransientNotification$stub$proxy#43c0c5f8 duration=0"
but when I set both the alarms simultaneously the notification is not shown when the mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); is executed
but the notification is shown when mAlarmManager.set(AlarmManager.RTC_WAKEUP, milli, pi); is executed. Also the notification is set for the original time i.e. 2'O clock and not after adding 15mins to it's duration.
Please help, I tried a lot of ways to call this functions at different places like after the 1st alarm is fired but all in vain.
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,0, intent, 0);
You have problem in this line. If you want to simultaneously fire two alarma then you should do something like this
PendingIntent sender = PendingIntent.getBroadcast(AlarmController.this,giveUniqueRequestIdsHere, intent, 0);
sender = PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), i, PendingIntent.FLAG_ONE_SHOT);
Do the same for your PendingIntent.getActivity();
Hi try using this to generate request I was generating my own request code but this line worked for me
final int intent_id = (int) System.currentTimeMillis();
When launch new OneShotAlarm.class, it have to design launch mode. Default setting would ignore the second time launch, if the first instance still existed.
Intent intent = new Intent(AlarmController.this, OneShotAlarm.class);
intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
seems like you forgot to set "sender2" before your second call.
you change the value of sender, then put sender2 as the argument.
You can create an array of your task in the Service class and set the array in the for loop, inside the for loop you can call your task simultaneously at the same time.
Try this:
Calendar cal = new GregorianCalendar();
Date date = cal.getTime();
cal.clear();
Cursor c = database.query(mArray.get(mPosition), new String[]{"days"},"days"+"!="+0, null, null, null, null);
cal.set(Calendar.YEAR,2011);
cal.set(Calendar.MONTH,date.getMonth());
cal.set(Calendar.DAY_OF_MONTH,date.getDate());
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(nextScreen.this, AlaramReciver.class);
i.putExtra("Start",mArray.get(mPosition));
Editor medit = getSharedPreferences("Start", 0).edit();
medit.putString("Start", mArray.get(mPosition));medit.commit();
PendingIntent pendingintent = PendingIntent.getBroadcast(this,mPosition, i, 0);
mgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingintent);
You have set to the time like this, and once you set time in alarm manager it will automatically call the functions daily. Use different request code for pendingintent.
If you want call second function. You just add the time in 15 min in the
cal.set(Calender.MINUTE,min+15);