/// <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(); } }
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); }
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())); } }