/// <summary>
        /// Save a geofence
        /// </summary>
        /// <param name="region">The GeofenceCircularRegion with the values you want to save in SharedPreferemces</param>
        public override void Save(GeofenceCircularRegion region)
        {
            if (!region.Persistent)
            {
                return;
            }

            string id = region.Id;
            // Get a SharedPreferences editor instance. Among other things, SharedPreferences ensures that updates are atomic and non-concurrent
            ISharedPreferencesEditor prefs = mPrefs.Edit();

            // Write the geofence values to SharedPreferences
            prefs.PutFloat(GetFieldKey(id, LatitudeGeofenceRegionKey), (float)region.Latitude);
            prefs.PutFloat(GetFieldKey(id, LongitudeGeofenceRegionKey), (float)region.Longitude);
            prefs.PutFloat(GetFieldKey(id, RadiusGeofenceRegionKey), (float)region.Radius);
            prefs.PutBoolean(GetFieldKey(id, NotifyOnEntryGeofenceRegionKey), region.NotifyOnEntry);
            prefs.PutBoolean(GetFieldKey(id, NotifyOnExitGeofenceRegionKey), region.NotifyOnExit);
            prefs.PutBoolean(GetFieldKey(id, NotifyOnStayGeofenceRegionKey), region.NotifyOnStay);
            prefs.PutString(GetFieldKey(id, NotificationEntryMessageGeofenceRegionKey), region.NotificationEntryMessage);
            prefs.PutString(GetFieldKey(id, NotificationExitMessageGeofenceRegionKey), region.NotificationExitMessage);
            prefs.PutString(GetFieldKey(id, NotificationStayMessageGeofenceRegionKey), region.NotificationStayMessage);
            prefs.PutBoolean(GetFieldKey(id, ShowNotificationGeofenceRegionKey), region.ShowNotification);
            prefs.PutBoolean(GetFieldKey(id, PersistentGeofenceRegionKey), region.Persistent);
            prefs.PutBoolean(GetFieldKey(id, ShowEntryNotificationGeofenceRegionKey), region.ShowEntryNotification);
            prefs.PutBoolean(GetFieldKey(id, ShowExitNotificationGeofenceRegionKey), region.ShowExitNotification);
            prefs.PutBoolean(GetFieldKey(id, ShowStayNotificationGeofenceRegionKey), region.ShowStayNotification);
            prefs.PutInt(GetFieldKey(id, StayedInThresholdDurationGeofenceRegionKey), (int)region.StayedInThresholdDuration.TotalMilliseconds);
            // Commit the changes
            prefs.Commit();
        }
        public override GeofenceCircularRegion Get(string id)
        {
            GeofenceCircularRegion region = null;

            if (!string.IsNullOrEmpty(NSUserDefaults.StandardUserDefaults.StringForKey(GetFieldKey(id, IdGeofenceRegionKey))))
            {
                double lat                       = NSUserDefaults.StandardUserDefaults.DoubleForKey(GetFieldKey(id, LatitudeGeofenceRegionKey));
                double lon                       = NSUserDefaults.StandardUserDefaults.DoubleForKey(GetFieldKey(id, LongitudeGeofenceRegionKey));
                bool   notifyOnEntry             = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, NotifyOnEntryGeofenceRegionKey));
                bool   notifyOnExit              = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, NotifyOnExitGeofenceRegionKey));
                bool   notifyOnStay              = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, NotifyOnStayGeofenceRegionKey));
                double radius                    = NSUserDefaults.StandardUserDefaults.DoubleForKey(GetFieldKey(id, RadiusGeofenceRegionKey));
                string notificationEntryMessage  = NSUserDefaults.StandardUserDefaults.StringForKey(GetFieldKey(id, NotificationEntryMessageGeofenceRegionKey));
                string notificationExitMessage   = NSUserDefaults.StandardUserDefaults.StringForKey(GetFieldKey(id, NotificationExitMessageGeofenceRegionKey));
                string notificationStayMessage   = NSUserDefaults.StandardUserDefaults.StringForKey(GetFieldKey(id, NotificationStayMessageGeofenceRegionKey));
                bool   showNotification          = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, ShowNotificationGeofenceRegionKey));
                bool   persistent                = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, PersistentGeofenceRegionKey));
                bool   showEntryNotification     = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, ShowEntryNotificationGeofenceRegionKey));
                bool   showExitNotification      = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, ShowExitNotificationGeofenceRegionKey));
                bool   showStayNotification      = NSUserDefaults.StandardUserDefaults.BoolForKey(GetFieldKey(id, ShowStayNotificationGeofenceRegionKey));
                int    stayedInThresholdDuration = (int)NSUserDefaults.StandardUserDefaults.IntForKey(GetFieldKey(id, StayedInThresholdDurationGeofenceRegionKey));

                region = new GeofenceCircularRegion(id, lat, lon, radius, notifyOnEntry, notifyOnExit, notifyOnStay, showNotification, persistent, showEntryNotification, showExitNotification, showStayNotification)
                {
                    NotificationEntryMessage  = notificationEntryMessage,
                    NotificationStayMessage   = notificationStayMessage,
                    NotificationExitMessage   = notificationExitMessage,
                    StayedInThresholdDuration = TimeSpan.FromMilliseconds(stayedInThresholdDuration)
                };
            }



            return(region);
        }
        void AddRegion(GeofenceCircularRegion region)
        {
            CLRegion cRegion = null;


            if (UIDevice.CurrentDevice.CheckSystemVersion(7, 0))
            {
                cRegion = new CLCircularRegion(new CLLocationCoordinate2D(region.Latitude, region.Longitude), (region.Radius > locationManager.MaximumRegionMonitoringDistance) ? locationManager.MaximumRegionMonitoringDistance : region.Radius, region.Id);
            }
            else
            {
                cRegion = new CLRegion(new CLLocationCoordinate2D(region.Latitude, region.Longitude), (region.Radius > locationManager.MaximumRegionMonitoringDistance) ? locationManager.MaximumRegionMonitoringDistance : region.Radius, region.Id);
            }


            cRegion.NotifyOnEntry = region.NotifyOnEntry || region.NotifyOnStay;
            cRegion.NotifyOnExit  = region.NotifyOnExit;


            locationManager.StartMonitoring(cRegion);

            // Request state for this region, putting request behind a timer per thread: http://stackoverflow.com/questions/24543814/diddeterminestate-not-always-called
            Task.Run(async() => {
                await Task.Delay(TimeSpan.FromSeconds(2));
                locationManager.RequestState(cRegion);
            });
        }
        /// <summary>
        /// Starts monitoring region
        /// </summary>
        /// <param name="region"></param>
        public void StartMonitoring(GeofenceCircularRegion region)
        {
            if (AvailableForMonitoring())
            {
                if (!mRegions.ContainsKey(region.Id))
                {
                    mRegions.Add(region.Id, region);
                }
                else
                {
                    mRegions[region.Id] = region;
                }
                GeofenceStore.SharedInstance.Save(region);

                if (Regions.Count > 20 && locationManager.MonitoredRegions.Count == 20)
                {
                    RecalculateRegions();
                }
                else
                {
                    AddRegion(region);
                }
                locationManager.StartMonitoringSignificantLocationChanges();
            }
        }
示例#5
0
        public override Dictionary <string, GeofenceCircularRegion> GetAll()
        {
            List <string> keys = mPrefs.All.Where(p => p.Key.ToString().StartsWith(GeofenceStoreId) && p.Key.Split('_').Length > 1).Select(p => p.Key.Split('_')[1]).Distinct().ToList();
            Dictionary <string, GeofenceCircularRegion> regions = new Dictionary <string, GeofenceCircularRegion>();

            foreach (string key in keys)
            {
                GeofenceCircularRegion region = Get(key);
                if (region != null)
                {
                    regions.Add(region.Id, region);
                }
            }
            return(regions);
        }
示例#6
0
 public GeofenceCircularRegion(GeofenceCircularRegion region)
 {
     Id                    = region.Id;
     Latitude              = region.Latitude;
     Longitude             = region.Longitude;
     Radius                = region.Radius;
     NotifyOnEntry         = region.NotifyOnEntry;
     NotifyOnExit          = region.NotifyOnExit;
     NotifyOnStay          = region.NotifyOnStay;
     ShowNotification      = region.ShowNotification;
     Persistent            = region.Persistent;
     ShowEntryNotification = region.ShowEntryNotification;
     ShowExitNotification  = region.ShowExitNotification;
     ShowStayNotification  = region.ShowStayNotification;
 }
        /// <summary>
        /// Starts monitoring specified region
        /// </summary>
        /// <param name="region"></param>
        public void StartMonitoring(GeofenceCircularRegion region)
        {
            lock (Lock)
            {
                if (IsMonitoring)
                {
                    mGeofencingClient.RemoveGeofences(GeofenceTransitionPendingIntent).AddOnCompleteListener(this);
                }

                if (!mRegions.ContainsKey(region.Id))
                {
                    mRegions.Add(region.Id, region);
                }
            }
            RequestMonitoringStart();
        }
        public override void Save(GeofenceCircularRegion region)
        {
            string id = region.Id;

            if (string.IsNullOrEmpty(id) || !region.Persistent)
            {
                return;
            }

            NSUserDefaults.StandardUserDefaults.SetString(region.Id, GetFieldKey(id, IdGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetDouble(region.Latitude, GetFieldKey(id, LatitudeGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetDouble(region.Longitude, GetFieldKey(id, LongitudeGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.NotifyOnEntry, GetFieldKey(id, NotifyOnEntryGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.NotifyOnExit, GetFieldKey(id, NotifyOnExitGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.NotifyOnStay, GetFieldKey(id, NotifyOnStayGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetDouble(region.Radius, GetFieldKey(id, RadiusGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.ShowNotification, GetFieldKey(id, ShowNotificationGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.Persistent, GetFieldKey(id, PersistentGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.ShowEntryNotification, GetFieldKey(id, ShowEntryNotificationGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.ShowExitNotification, GetFieldKey(id, ShowExitNotificationGeofenceRegionKey));
            NSUserDefaults.StandardUserDefaults.SetBool(region.ShowStayNotification, GetFieldKey(id, ShowStayNotificationGeofenceRegionKey));

            NSUserDefaults.StandardUserDefaults.SetInt((int)region.StayedInThresholdDuration.TotalMilliseconds, GetFieldKey(id, StayedInThresholdDurationGeofenceRegionKey));

            if (!string.IsNullOrEmpty(region.NotificationEntryMessage))
            {
                NSUserDefaults.StandardUserDefaults.SetString(region.NotificationEntryMessage, GetFieldKey(id, NotificationEntryMessageGeofenceRegionKey));
            }

            if (!string.IsNullOrEmpty(region.NotificationExitMessage))
            {
                NSUserDefaults.StandardUserDefaults.SetString(region.NotificationExitMessage, GetFieldKey(id, NotificationExitMessageGeofenceRegionKey));
            }

            if (!string.IsNullOrEmpty(region.NotificationStayMessage))
            {
                NSUserDefaults.StandardUserDefaults.SetString(region.NotificationStayMessage, GetFieldKey(id, NotificationStayMessageGeofenceRegionKey));
            }

            geofenceIds.Add(id);

            NSUserDefaults.StandardUserDefaults.SetString(string.Join(IdSeparator, geofenceIds.ToArray <string>()), GeofenceIdsKey);

            NSUserDefaults.StandardUserDefaults.Synchronize();
        }
 /// <summary>
 /// Saves geofence region in store
 /// </summary>
 /// <param name="region"></param>
 public abstract void Save(GeofenceCircularRegion region);
        /// <summary>
        /// Handles geofence intent arrival
        /// </summary>
        /// <param name="intent"></param>
        protected override void OnHandleIntent(Intent intent)
        {
            try
            {
                lock (IntentLock)
                {
                    if (intent == null)
                    {
                        intent = new Intent(Application.Context, typeof(GeofenceTransitionsIntentService));
                    }

                    Context context = Android.App.Application.Context;
                    Bundle  extras  = intent.Extras;
                    Android.Gms.Location.GeofencingEvent geofencingEvent = Android.Gms.Location.GeofencingEvent.FromIntent(intent);

                    if (geofencingEvent.HasError)
                    {
                        string errorMessage = Android.Gms.Location.GeofenceStatusCodes.GetStatusCodeString(geofencingEvent.ErrorCode);
                        string message      = string.Format("{0} - {1}", CrossGeofence.Id, errorMessage);
                        System.Diagnostics.Debug.WriteLine(message);
                        ((GeofenceImplementation)CrossGeofence.Current).LocationHasError = true;
                        CrossGeofence.GeofenceListener.OnError(message);
                        return;
                    }

                    // Get the geofences that were triggered. A single event can trigger multiple geofences.
                    IList <Android.Gms.Location.IGeofence> triggeringGeofences = geofencingEvent.TriggeringGeofences;
                    List <GeofenceResult> geofenceTransitions = new List <GeofenceResult>();
                    Dictionary <string, GeofenceCircularRegion> transitionRegions = new Dictionary <string, GeofenceCircularRegion>();
                    if (triggeringGeofences != null)
                    {
                        foreach (Android.Gms.Location.IGeofence geofence in triggeringGeofences)
                        {
                            if (geofence == null)
                            {
                                continue;
                            }
                            int geofenceTransition         = geofencingEvent.GeofenceTransition;
                            GeofenceTransition gTransition = GeofenceTransition.Unknown;
                            // Get the transition type.
                            lock (GeofenceImplementation.Lock)
                            {
                                ((GeofenceImplementation)CrossGeofence.Current).CurrentRequestType = Plugin.Geofence.GeofenceImplementation.RequestType.Update;
                                if (!CrossGeofence.Current.GeofenceResults.ContainsKey(geofence.RequestId))
                                {
                                    ((GeofenceImplementation)CrossGeofence.Current).AddGeofenceResult(geofence.RequestId);
                                }
                                GeofenceResult result = CrossGeofence.Current.GeofenceResults[geofence.RequestId];

                                //geofencingEvent.TriggeringLocation.Accuracy
                                result.Latitude  = geofencingEvent.TriggeringLocation.Latitude;
                                result.Longitude = geofencingEvent.TriggeringLocation.Longitude;
                                result.Accuracy  = geofencingEvent.TriggeringLocation.Accuracy;

                                double   seconds    = geofencingEvent.TriggeringLocation.Time / 1000;
                                DateTime resultDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(seconds).ToLocalTime();
                                switch (geofenceTransition)
                                {
                                case Android.Gms.Location.Geofence.GeofenceTransitionEnter:
                                    gTransition          = GeofenceTransition.Entered;
                                    result.LastEnterTime = resultDate;
                                    result.LastExitTime  = null;
                                    break;

                                case Android.Gms.Location.Geofence.GeofenceTransitionExit:
                                    gTransition         = GeofenceTransition.Exited;
                                    result.LastExitTime = resultDate;
                                    break;

                                case Android.Gms.Location.Geofence.GeofenceTransitionDwell:
                                    gTransition = GeofenceTransition.Stayed;
                                    break;

                                default:
                                    string message = string.Format("{0} - {1}", CrossGeofence.Id, "Invalid transition type");
                                    System.Diagnostics.Debug.WriteLine(message);
                                    gTransition = GeofenceTransition.Unknown;
                                    break;
                                }
                                System.Diagnostics.Debug.WriteLine($"{CrossGeofence.Id} - {result.RegionId} - Transition: {gTransition}");
                                if (result.Transition != gTransition)
                                {
                                    result.Transition = gTransition;
                                    geofenceTransitions.Add(new GeofenceResult(result));
                                    if (CrossGeofence.Current.Regions.ContainsKey(result.RegionId))
                                    {
                                        GeofenceCircularRegion region = CrossGeofence.Current.Regions[result.RegionId];
                                        transitionRegions.Add(result.RegionId, new GeofenceCircularRegion(region));
                                    }
                                    //Check if device has stayed in region asynchronosly
                                    //Commented because is already handled using DWELL on Android
                                    //CheckIfStayed(geofence.RequestId);
                                }
                            }
                        }
                    }

                    Task.Factory.StartNew(() =>
                    {
                        foreach (GeofenceResult result in geofenceTransitions)
                        {
                            if (result == null)
                            {
                                continue;
                            }
                            CrossGeofence.GeofenceListener.OnRegionStateChanged(result);
                            if (transitionRegions.ContainsKey(result.RegionId))
                            {
                                GeofenceCircularRegion region = transitionRegions[result.RegionId];
                                if (region.ShowNotification)
                                {
                                    string message = result.ToString();
                                    switch (result.Transition)
                                    {
                                    case GeofenceTransition.Entered:
                                        if (!region.ShowEntryNotification)
                                        {
                                            return;
                                        }
                                        message = string.IsNullOrEmpty(region.NotificationEntryMessage) ? message : region.NotificationEntryMessage;
                                        break;

                                    case GeofenceTransition.Exited:
                                        if (!region.ShowExitNotification)
                                        {
                                            return;
                                        }
                                        message = string.IsNullOrEmpty(region.NotificationExitMessage) ? message : region.NotificationExitMessage;
                                        break;

                                    case GeofenceTransition.Stayed:
                                        if (!region.ShowStayNotification)
                                        {
                                            return;
                                        }
                                        message = string.IsNullOrEmpty(region.NotificationStayMessage) ? message : region.NotificationStayMessage;
                                        break;
                                    }
                                    using (Handler handler = new Handler(Looper.MainLooper))
                                    {
                                        handler.Post(() =>
                                        {
                                            CreateNotification(context.ApplicationInfo.LoadLabel(context.PackageManager), message);
                                        });
                                    }
                                }
                            }
                        }
                    });
                }
            }
            catch (Java.Lang.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, ex.ToString()));
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("{0} - {1}", CrossGeofence.Id, ex.ToString()));
            }
        }