protected override void ScheduleCallbackPlatformSpecific(ScheduledCallback callback) { // get the callback information. this can be null if we don't have all required information. don't schedule the notification if this happens. NSMutableDictionary callbackInfo = GetCallbackInfo(callback); if (callbackInfo == null) { return; } Action <UILocalNotification> notificationCreated = notification => { lock (_callbackIdNotification) { _callbackIdNotification.Add(callback.Id, notification); } }; IUILocalNotificationNotifier notifier = SensusContext.Current.Notifier as IUILocalNotificationNotifier; if (callback.Silent) { notifier.IssueSilentNotificationAsync(callback.Id, callback.NextExecution.Value, callbackInfo, notificationCreated); } else { notifier.IssueNotificationAsync(callback.Protocol?.Name ?? "Alert", callback.UserNotificationMessage, callback.Id, callback.Protocol, true, callback.DisplayPage, callback.NextExecution.Value, callbackInfo, notificationCreated); } }
protected override void ScheduleCallbackAsync(string callbackId, int delayMS, bool repeating, int repeatDelayMS, bool repeatLag) { // get the callback information. this can be null if we don't have all required information. don't schedule the notification if this happens. DisplayPage displayPage = GetCallbackDisplayPage(callbackId); NSMutableDictionary callbackInfo = GetCallbackInfo(callbackId, repeating, repeatDelayMS, repeatLag, displayPage); if (callbackInfo == null) { return; } Action <UILocalNotification> notificationCreated = notification => { lock (_callbackIdNotification) { _callbackIdNotification.Add(callbackId, notification); } }; IUILocalNotificationNotifier notifier = SensusContext.Current.Notifier as IUILocalNotificationNotifier; string userNotificationMessage = GetCallbackUserNotificationMessage(callbackId); if (userNotificationMessage == null) { notifier.IssueSilentNotificationAsync(callbackId, delayMS, callbackInfo, notificationCreated); } else { notifier.IssueNotificationAsync("Sensus", userNotificationMessage, callbackId, true, displayPage, delayMS, callbackInfo, notificationCreated); } }
public override void CancelSilentNotifications() { SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { IUILocalNotificationNotifier notifier = SensusContext.Current.Notifier as IUILocalNotificationNotifier; foreach (UILocalNotification scheduledNotification in UIApplication.SharedApplication.ScheduledLocalNotifications) { if (TryGetCallback(scheduledNotification.UserInfo)?.Silent ?? false) { notifier.CancelNotification(scheduledNotification); } } }); }
public override void UpdateCallbackNotifications() { SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { // this method will be called in one of three conditions: (1) after sensus has been started and is running, (2) // after sensus has been reactivated and was already running, and (3) after a start attempt was made but failed. // in all three situations, there will be zero or more notifications present in the _callbackIdNotification lookup. // in (1), the notifications will have just been created and will have activation IDs set to the activation ID of // the current object. in (2), the notifications will have stale activation IDs. in (3), there will be no notifications. // the required post-condition of this method is that any present notification objects have activation IDs set to // the activation ID of the current object. so...let's make that happen. lock (_callbackIdNotification) { IUILocalNotificationNotifier notifier = SensusContext.Current.Notifier as IUILocalNotificationNotifier; // copy key list since servicing/raising the callback is going to modify the collection temporarily foreach (string callbackId in _callbackIdNotification.Keys.ToList()) { UILocalNotification notification = _callbackIdNotification[callbackId]; double msTillTrigger = 0; DateTime?triggerDateTime = notification.FireDate?.ToDateTime().ToLocalTime(); if (triggerDateTime.HasValue) { msTillTrigger = (triggerDateTime.Value - DateTime.Now).TotalMilliseconds; } // service any callback that should have already been serviced or will soon be serviced if (msTillTrigger < 5000) { notifier.CancelNotification(notification); ServiceCallbackAsync(notification.UserInfo); } // all other callbacks will have upcoming notification deliveries, except for silent notifications, which were canceled when the // app was backgrounded. re-issue those silent notifications now. else if (iOSNotifier.IsSilent(notification.UserInfo)) { notifier.IssueNotificationAsync(notification); } } } }); }
/// <summary> /// Updates the callbacks by running any that should have already been serviced or will be serviced in the near future. /// Also reissues all silent notifications, which would have been canceled when the app went into the background. /// </summary> /// <returns>The callbacks async.</returns> public override Task UpdateCallbacksAsync() { return(Task.Run(() => { IUILocalNotificationNotifier notifier = SensusContext.Current.Notifier as IUILocalNotificationNotifier; // get a list of notifications to update. cannot iterate over the notifications directly because the raising // process is going to temporarily modify the collection. List <UILocalNotification> notifications = null; lock (_callbackIdNotification) { notifications = _callbackIdNotification.Values.ToList(); } foreach (UILocalNotification notification in notifications) { // the following needs to be done on the main thread since we're working with UILocalNotification objects. SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { TimeSpan timeTillTrigger = TimeSpan.Zero; DateTime?triggerDateTime = notification.FireDate?.ToDateTime().ToLocalTime(); if (triggerDateTime.HasValue) { timeTillTrigger = triggerDateTime.Value - DateTime.Now; } // service any callback that should have already been serviced or will soon be serviced if (timeTillTrigger.TotalSeconds < 5) { notifier.CancelNotification(notification); ServiceCallbackAsync(notification.UserInfo); } // all other callbacks will have upcoming notification deliveries, except for silent notifications, which were canceled when the // app was backgrounded. re-issue those silent notifications now. else if (iOSNotifier.IsSilent(notification.UserInfo)) { notifier.IssueNotificationAsync(notification); } }); } })); }