Clockplus/app/src/main/java/com/philliphsu/clock2/PendingAlarmScheduler.java

58 lines
2.8 KiB
Java

package com.philliphsu.clock2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.philliphsu.clock2.model.DatabaseManager;
import com.philliphsu.clock2.util.AlarmController;
import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
/**
* Used to reschedule recurring alarms that were dismissed in their upcoming state, so {@link Alarm#ringsAt()}
* still refers to the time it rings today. This class receives
* your intent at the Alarm instance's normal ring time, so by the time you make a subsequent call
* to {@link Alarm#ringsAt()}, the value returned refers to the next time the alarm will recur.
*/
// TODO: Consider registering this locally instead of in the manifest.
public class PendingAlarmScheduler extends BroadcastReceiver {
// We include the class name in the string to distinguish this constant from the one defined
// in UpcomingAlarmReceiver.
public static final String EXTRA_ALARM_ID = "com.philliphsu.clock2.PendingAlarmScheduler.extra.ALARM_ID";
@Override
public void onReceive(final Context context, Intent intent) {
final long id = intent.getLongExtra(EXTRA_ALARM_ID, -1);
if (id < 0) {
throw new IllegalStateException("No alarm id received");
}
// Start our own thread to load the alarm instead of:
// * using a Loader, because we have no complex lifecycle and thus
// BroadcastReceiver has no built-in LoaderManager, AND getting a Loader
// to work here might be a hassle, let alone it might not even be appropriate to
// use Loaders outside of an Activity/Fragment, since it does depend on LoaderCallbacks.
// * using an AsyncTask, because we don't need to do anything on the UI thread
// after the background work is complete.
// TODO: Verify using a Runnable like this won't cause a memory leak.
// It *probably* won't because a BroadcastReceiver doesn't hold a Context,
// and it also doesn't have a lifecycle, so it likely won't stick around
// in memory.
new Thread(new Runnable() {
@Override
public void run() {
Alarm alarm = checkNotNull(DatabaseManager
.getInstance(context).getAlarm(id));
if (!alarm.isEnabled()) {
throw new IllegalStateException("Alarm must be enabled!");
}
alarm.ignoreUpcomingRingTime(false); // allow #ringsWithinHours() to behave normally
// No UI work is done
AlarmController controller = new AlarmController(context, null);
controller.scheduleAlarm(alarm, false);
controller.save(alarm);
}
}).start();
}
}