package org.gingercal; import java.util.List; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import org.gingercal.Model.Ev; /** Local notifications before timed events, driven from the cached agenda. */ public final class Reminders { private Reminders() {} static PendingIntent alarmIntent(Context c) { Intent i = new Intent(c, AlarmReceiver.class); i.setAction(AlarmReceiver.REMIND); return PendingIntent.getBroadcast(c, 2, i, 0x08000000 /* FLAG_UPDATE_CURRENT */); } public static void schedule(Context c) { AlarmManager am = (AlarmManager) c.getSystemService("alarm"); PendingIntent pi = alarmIntent(c); am.cancel(pi); int m = App.remind(c); if (m < 0) return; long now = System.currentTimeMillis(); long notified = App.prefs(c).getLong("notified", 0); long next = Db.get(c).nextStartAfter(Math.max(notified, now - 60000L)); if (next < 0) return; am.set(0 /* RTC_WAKEUP */, Math.max(now + 1000, next - m * ICal.MIN), pi); } public static void fire(Context c) { int m = App.remind(c); if (m < 0) return; long now = System.currentTimeMillis(); long notified = App.prefs(c).getLong("notified", 0); // never nag about things that started more than 30 minutes ago List due = Db.get(c).startingBetween(Math.max(notified, now - 30 * ICal.MIN), now + m * ICal.MIN + 30000L); NotificationManager nm = (NotificationManager) c.getSystemService("notification"); long newest = notified; int icon = App.sysDrawable(c, "ic_popup_reminder"); if (icon == 0) icon = App.sysDrawable(c, "ic_dialog_info"); for (Ev e : due) { Intent open = new Intent(c, MainActivity.class); open.setFlags(0x10000000 /* FLAG_ACTIVITY_NEW_TASK */); PendingIntent pi = PendingIntent.getActivity(c, 0, open, 0); Notification n = new Notification(icon, e.title, e.start); String body = App.when(c, e) + (e.location.length() > 0 ? " ยท " + e.location : ""); n.setLatestEventInfo(c, e.title.length() > 0 ? e.title : L.t("(no title)"), body, pi); n.flags |= 16; // FLAG_AUTO_CANCEL n.defaults = -1; // DEFAULT_ALL: sound, vibrate, lights nm.notify((e.href + e.start).hashCode(), n); if (e.start > newest) newest = e.start; } if (newest != notified) App.prefs(c).edit().putLong("notified", newest).commit(); schedule(c); } }