public static void ScheduleDayBeforeAlarm(Context context, AccountDataItem account, DateTime today, AgendaViewItemsGroup agendaItems) { if (agendaItems == null) { return; } DateTime dayBeforeReminderTime = RemindersExtension.GetDayBeforeReminderTime(today, account, agendaItems); DateTime timeToScheduleAt; // If we haven't reached that time yet for "due tomorrow" if (dayBeforeReminderTime > DateTime.Now) { timeToScheduleAt = dayBeforeReminderTime.AddMilliseconds(1); } // Otherwise we'll need to set the timer for the "due today" else { timeToScheduleAt = today.AddDays(1).AddMilliseconds(1); } AlarmManagerHelper.Schedule( context: context, receiverType: typeof(UpdateDayBeforeNotificationReceiver), wakeTime: timeToScheduleAt, uriData: "powerplanner:?localAccountId=" + account.LocalAccountId, wakeDevice: true); }
private async Task AddScheduledDayBeforeNotifications(AccountDataItem account, AgendaViewItemsGroup agendaItems, DateTime now) { try { string idStartString = GetIdentifierStartStringForDayBefore(account.LocalAccountId); DateTime artificialToday = now.Date; for (int i = 0; i < DAYS_IN_ADVANCE; i++, artificialToday = artificialToday.AddDays(1)) { DateTime artificialTomorrow = artificialToday.AddDays(1); BaseViewItemHomeworkExam[] itemsOnDay = agendaItems.Items.Where(x => x.Date.Date == artificialTomorrow).OrderBy(x => x).ToArray(); if (itemsOnDay.Length > 0) { DateTime reminderTime = RemindersExtension.GetDayBeforeReminderTime(artificialToday, account, agendaItems); string title = "Due tomorrow"; string body = ""; if (itemsOnDay.Length == 1) { body = StringTools.TrimLengthWithEllipses(itemsOnDay[0].Name, 200); } else { title += " (" + itemsOnDay.Length + ")"; foreach (var item in itemsOnDay.Take(5)) { body += StringTools.TrimLengthWithEllipses(item.Name, 30) + "\n"; } body = body.Trim(); } await ScheduleDayBeforeNotification(idStartString + artificialToday.ToString(DAY_BEFORE_DATE_FORMAT, CultureInfo.InvariantCulture), title, body, reminderTime); } } } catch (Exception ex) { TelemetryExtension.Current?.TrackException(ex); } }
private static async Task UpdateDayBeforeNotification(AccountDataItem account, AgendaViewItemsGroup agendaItems, Context context, NotificationManager notificationManager, bool fromForeground) { string tag = account.LocalAccountId.ToString(); // If no current semester, or no items, then just clear if (agendaItems == null || agendaItems.Items.Count == 0) { notificationManager.Cancel(tag, NotificationIds.DAY_BEFORE_NOTIFICATION); return; } StatusBarNotification existing; if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.M) { existing = notificationManager.GetActiveNotifications().FirstOrDefault(i => i.Id == NotificationIds.DAY_BEFORE_NOTIFICATION && i.Tag == tag); } else { // GetActiveNotifications didn't exist till API 23 existing = null; } const string EXTRA_UNIQUE_ID = "UniqueId"; DateTime now = DateTime.Now; DateTime reminderTime = RemindersExtension.GetDayBeforeReminderTime(now.Date, account, agendaItems); bool sendingDueTomorrow = now >= reminderTime; NotificationCompat.Builder builder; if (sendingDueTomorrow) { var itemsDueTomorrow = agendaItems.Items.Where(i => i.Date.Date == now.Date.AddDays(1)).OrderBy(i => i).ToArray(); // If nothing tomorrow, we clear if (itemsDueTomorrow.Length == 0) { notificationManager.Cancel(tag, NotificationIds.DAY_BEFORE_NOTIFICATION); return; } string extraUniqueId = "DueTomorrow" + string.Join(";", itemsDueTomorrow.Select(i => i.Name)).GetHashCode(); // If already updated if (existing != null && existing.Notification.Extras.GetString(EXTRA_UNIQUE_ID).Equals(extraUniqueId)) { return; } // If all the items have been updated more recently than the reminder time, we won't show a new notification if (existing == null && itemsDueTomorrow.All(i => i.Updated.ToLocalTime() > reminderTime)) { return; } // If we already sent the notification today if (account.DateLastDayBeforeReminderWasSent.Date == now.Date) { // If the notification has been dismissed, do nothing if (existing == null) { return; } } // Otherwise we need to update the date that it was sent else { account.DateLastDayBeforeReminderWasSent = now; await AccountsManager.Save(account); } if (existing == null && fromForeground) { return; } builder = CreateReminderBuilderForDayBefore(context, account.LocalAccountId); Bundle b = new Bundle(); b.PutString(EXTRA_UNIQUE_ID, extraUniqueId); builder.SetExtras(b); // "Due tomorrow" builder.SetContentTitle(PowerPlannerResources.GetDueX(PowerPlannerResources.GetRelativeDateTomorrow().ToLower())); PopulateNotificationDayBeforeWithItems(builder, itemsDueTomorrow); } // Otherwise "due today" else { var itemsDueToday = agendaItems.Items.Where(i => i.Date.Date == now.Date).OrderBy(i => i).ToArray(); // If nothing left today, we clear if (itemsDueToday.Length == 0) { notificationManager.Cancel(tag, NotificationIds.DAY_BEFORE_NOTIFICATION); return; } string extraUniqueId = "DueToday" + string.Join(";", itemsDueToday.Select(i => i.Name)).GetHashCode(); // If already updated if (existing != null && existing.Notification.Extras.GetString(EXTRA_UNIQUE_ID).Equals(extraUniqueId)) { return; } // If the notification doesn't currently exist (user potentially dismissed it) and we've already sent either yesterday or today if (existing == null && account.DateLastDayBeforeReminderWasSent.Date == DateTime.Today.AddDays(-1) || account.DateLastDayBeforeReminderWasSent.Date == DateTime.Today) { return; } // If all the items have been updated more recently than the reminder time, we won't show a new notification if (existing == null && itemsDueToday.All(i => i.Updated.ToLocalTime() > reminderTime)) { return; } // If we already sent the notification yesterday if (account.DateLastDayBeforeReminderWasSent.Date == now.Date.AddDays(-1)) { // If the notification has been dismissed, do nothing if (existing == null) { return; } } // Otherwise we need to update the date that it was sent else { account.DateLastDayBeforeReminderWasSent = now.Date.AddDays(-1); await AccountsManager.Save(account); } if (existing == null && fromForeground) { return; } builder = CreateReminderBuilderForDayBefore(context, account.LocalAccountId); Bundle b = new Bundle(); b.PutString(EXTRA_UNIQUE_ID, extraUniqueId); builder.SetExtras(b); // "Due today" builder.SetContentTitle(PowerPlannerResources.GetDueX(PowerPlannerResources.GetRelativeDateToday().ToLower())); PopulateNotificationDayBeforeWithItems(builder, itemsDueToday); } notificationManager.Notify(tag, NotificationIds.DAY_BEFORE_NOTIFICATION, BuildReminder(builder)); }