Razgriz
Razgriz

Reputation: 7343

Alarm Manager set Daily Alarm at a specific time?

I've been working on this application that is supposed to run at a given time daily, except on weekends. I've used an AlarmBroadCastReceiver to fire a certain block of code at a given time. I have this code in my AlarmBroadCastReceiver class:

public void SetAlarm(Context context) {
    AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
    intent.putExtra(ONE_TIME, Boolean.FALSE);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 2);
    calendar.set(Calendar.MINUTE, 30);
    calendar.set(Calendar.SECOND, 0);
    am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 0, pi);

}

Basically I try and set a repeating alarm on that time.

Then at a press of a button, I have this in my MainActivity where I'm calling it from:

public void onStartAlarmClicked(View view){
    Context context = this.getApplicationContext();
    if(alarm != null){
        Log.e(TAG, "starting alarm");
        alarm.SetAlarm(context);
    }else{
        Log.e(TAG, "Alarm is null");
    }
}

where alarm is an object of the AlarmBroadCastReceiver class.

The problem I have with it is that the code only fires once. Once it hits 2:30, it fires. However, when I set the time back to 2:29 and wait for 2:30, or set the date 1 day forward and then set the time to 2:20 and wait for 2:30, the code no longer fires.

I have a feeling I'm overlooking something rather simple with regards to setting the alarm time but I can't see it right now.

Upvotes: 3

Views: 5672

Answers (2)

Razgriz
Razgriz

Reputation: 7343

Found a better answer from this answer. Tweaked it a bit.

public void Set12nnAlarm(Context context) {

    AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
    intent.putExtra(ONE_TIME, Boolean.FALSE);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);

    // every day at 9 am
    Calendar calendar = Calendar.getInstance();

    calendar.setTimeInMillis(System.currentTimeMillis());

    // if it's after or equal 9 am schedule for next day
    if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 9) {
        Log.e(TAG, "Alarm will schedule for next day!");
        calendar.add(Calendar.DAY_OF_YEAR, 1); // add, not set!
    }
    else{
        Log.e(TAG, "Alarm will schedule for today!");
    }
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);


    am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, pi);
}

Upvotes: 5

lionscribe
lionscribe

Reputation: 3513

You have to setup a BroadcastReceiver to listen to time and date changes, and then reset the alarm. As you want the receiver to be triggered at all times, it is better to set in the Manifest.

Create class in own file

public class DateTimeChangeReceiver extends BroadcastReceiver {
    @Override 
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action.equals(Intent.ACTION_TIME_CHANGED) ||
            action.equals(Intent.ACTION_TIMEZONE_CHANGED) ||
            action.equals(Intent.ACTION_DATE_CHANGED))
        { 
            resetAlarm(); 
        } 
    } 
} 

And in the Manifest

<receiver android:name=".DateTimeChangeReceiver ">
    <intent_filter>
            <action android:name="android.intent.action.TIMEZONE_CHANGED" />
            <action android:name="android.intent.action.TIME_SET" />
            <action android:name="android.intent.action.DATE_CHANGED" />
    </intent_filter>
</receiver>

Upvotes: 2

Related Questions