I have an application that uses alarms
using AlarmManager
. I set an alarm at a certain time and, when it triggers, it's set again 2 hours later. The second time the alarm is triggered it's not set again, so it's triggered just 2 times.
To know if the alarm triggered is the first one or the second I pass a boolean
as a parameter to the BroadcastReceiver, like this:
Bundle b = new Bundle();
b.putBoolean(TODAlarm.KEY_IS_INFRACTION, true);
Intent intent = new Intent(me, TODAlarm.class);
intent.putExtras(b);
PendingIntent pendingIntent = PendingIntent.getBroadcast(me, TODAlarm.TYPE_DAILY_REST_NEEDED,
intent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.set(AlarmManager.RTC_WAKEUP, time+2*HOURS, pendingIntent);
The first time I program the alarm I set KEY_IS_INFRACTION to false. When it's triggered I use the code from above and set it to true.
If I reinstall the application (using Eclipse
->Run) when the alarm has been triggered once (I have an alarm programmed with KEY_IS_INFRACTION = true but it hasn't been triggered yet) the alarm programmed after the reinstall has KEY_IS_INFRACTION = false, but the intent received by the BroadcastReceiver
has KEY_IS_INFRACTION = true (it seems like it receives the alarm programmed BEFORE reinstalling the application, even if I use alarmManager.cancel). This only happens when I reinstall the application, if I reboot the phone the intent received is ok. I always use alarmManager.cancel before alarmManager.set, but it's not working either.
The final application won't be reinstalled often, but if I publish an update this could lead to errors in the application behaviour. Anybody knows how can I fix it?
Here's the CORRECT sequence of actions (what the application should do):
1- Install aplication. Alarm is set to hour X with INFRACTION = false.
2- Hour X is reached and the alarm is triggered. The BroadcastReceiver
receives an intent with INFRACTION = false and the alarm is set again with INFRACTION = true.
3- Reinstall application. Alarm is set to hour X with INFRACTION = false. Since hour X has already passed, the alarm is triggered. The BroadcastReceiver
receives an intent with INFRACTION = false and the alarm is set again with INFRACTION = true.
Here's what it REALLY happens:
1- Install aplication. Alarm is set to hour X with INFRACTION = false.
2- Hour X is reached and the alarm is triggered. The BroadcastReceiver
receives an intent with INFRACTION = false and the alarm is set again with INFRACTION = true.
3- Reinstall application. Alarm is set to hour X with INFRACTION = false. Since hour X has already passed, the alarm is triggered. The BroadcastReceiver
receives an intent with INFRACTION = true and the alarm isn't set again.
[EDIT] Add some code. This is the function to set the alarm when the application is first started:
private void setNeededRestAlarmOrWarning(int type, long timeToStart){
Bundle b = new Bundle();
b.putInt(TODAlarm.KEY_ALARM_TYPE, type);
if(type == TODAlarm.TYPE_DAILY_REST_NEEDED){
b.putBoolean(TODAlarm.KEY_IS_INFRACTION, arr_bControls[CONTROL_PERMITIR_DORMIR_9_HORAS] ||
arr_iControls[CONTROL_LIMIT_TO_RECUPERATE] == 0 ||
arr_iControls[CONTROL_TIME_TO_RECUPERATE_COUNTER] >= Times.CTRL_PERMITTED_DESCANSOS_REDUCIDOS_POR_SEMANA);
Log.d(TAG, "INFRACTION IS "+b.getBoolean(TODAlarm.KEY_IS_INFRACTION));
}
Intent intent = new Intent(me, TODAlarm.class);
intent.putExtras(b);
PendingIntent pendingIntent = PendingIntent.getBroadcast(me, type,
intent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.set(AlarmManager.RTC_WAKEUP, timeToStart, pendingIntent);
}
When the alarm is triggered I use the code posted above, before the EDIT.
[/EDIT]