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);
                        }
                    }
                }
            });
        }
Пример #5
0
        /// <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);
                        }
                    });
                }
            }));
        }