GPS tracking and geofence monitoring for .NET MAUI, iOS, and Android using Shiny.Locations
GPS tracking and geofence monitoring for .NET MAUI, iOS, and Android applications with full foreground and background support.
Use this skill when the user needs to:
| Property | Value |
|---|---|
| NuGet | Shiny.Locations |
| Namespace | Shiny.Locations |
| Platforms | iOS, Android, WebAssembly |
| DI Namespace | Shiny (extension methods on IServiceCollection) |
| Support Library | Shiny.Support.Locations (provides Position and Distance) |
Register GPS in MauiProgram.cs:
// GPS without a background delegate (foreground only)
services.AddGps();
// GPS with a background delegate
services.AddGps<MyGpsDelegate>();
Register geofencing in MauiProgram.cs:
// Standard geofencing with a delegate
services.AddGeofencing<MyGeofenceDelegate>();
// GPS-direct geofencing (uses realtime GPS - battery intensive)
services.AddGpsDirectGeofencing<MyGeofenceDelegate>();
When generating code for Shiny.Locations:
RequestAccess and check the returned AccessState before calling StartListener or StartMonitoring.GpsRequest factories or constructor based on the background mode needed:
GpsRequest.Foreground for foreground-only use (equivalent to new GpsRequest(GpsBackgroundMode.None))new GpsRequest(GpsBackgroundMode.Standard) for standard background (iOS: significant location changes; Android: 3-4 updates/hour)GpsRequest.Realtime(true) for background realtime with precise accuracy (iOS/Android: updates every 1 second)IGpsManager or IGeofenceManager via constructor injection. Never instantiate managers directly.IGpsDelegate for background GPS processing, or subclass the abstract GpsDelegate base class for built-in filtering by distance/time and stationary detection.IGeofenceDelegate for geofence enter/exit events.Position record with (latitude, longitude) -- latitude range is -90 to 90, longitude range is -180 to 180.Distance factory methods -- Distance.FromMeters(), Distance.FromKilometers(), Distance.FromMiles(). Never construct Distance directly with kilometers unless intentional.GetCurrentPosition(), GetLastReadingOrCurrentPosition(), IsListening(), IsPositionInside(), IsInsideRegion().WhenReading() for UI bindings (observable stream). Use delegates for background processing.GeofenceRegion, always provide a unique Identifier string. The SingleUse parameter removes the region after the first trigger.Task or Task<T>.IObservable<T> from System.Reactive.GpsBackgroundMode enum controls background behavior: None (foreground), Standard (periodic), Realtime (continuous).GeofenceState enum values: Unknown, Entered, Exited.AccessState is from Shiny.Core and includes Available, Denied, Disabled, Restricted, NotSupported, Unknown.AccessState before starting GPS or geofence monitoring. Handle Denied and Restricted states gracefully with user-facing messaging.GpsBackgroundMode.Standard over Realtime to conserve battery. Only use Realtime when continuous tracking is required.StopListener() / StopAllMonitoring()).GpsDelegate base class instead of implementing IGpsDelegate directly. It provides MinimumDistance, MinimumTime filtering, and stationary detection out of the box.GetCurrentPosition() extension method which handles starting/stopping the listener automatically.IObservable subscriptions from WhenReading() when the view/page is no longer active.NSLocationWhenInUseUsageDescription and NSLocationAlwaysAndWhenInUseUsageDescription in Info.plist.ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, and ACCESS_BACKGROUND_LOCATION permissions in AndroidManifest.xml.