1

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]

PX Developer
  • 8,065
  • 7
  • 42
  • 66
  • I'm guessing that this is due to the way you are checking if the alarm has already been triggered. What code do you use to determine what INFRACTION value to set? – jamesc Apr 24 '13 at 11:22
  • To check if the alarm has been triggered I use some control variables, it's a bit complex. But I log b.getBoolean(TODAlarm.KEY_IS_INFRACTION) right before setting the alarm. My log says: ALARM SET WITH INFRACTION = FALSE. ALARM RECEIVED WITH INFRACTION = TRUE. It doesn't make sense :S – PX Developer Apr 24 '13 at 11:31
  • I added some code to the post, although I don't think it will be any useful. – PX Developer Apr 24 '13 at 11:33
  • After some thought I'm wondering if it would be better to use saved preferences instead of passing an extra to the broadcast receiver. That way the receiver could look at saved preferences at the time it is invoked that way it doesn't matter when the alarm manager was triggered the receiver will ALWAYS get the current state from preferences – jamesc Apr 24 '13 at 16:18
  • I've done it with SharedPreferences and now it works, thanks! It's really annoying I can't use the Intent to pass that data :S – PX Developer Apr 25 '13 at 07:52

0 Answers0