with one click
shiny-locations
// GPS tracking, geofence monitoring, and motion activity recognition for .NET MAUI, iOS, and Android using Shiny.Locations
// GPS tracking, geofence monitoring, and motion activity recognition for .NET MAUI, iOS, and Android using Shiny.Locations
Generate code using Shiny.BluetoothLE.Hosting, a BLE peripheral hosting library for .NET with GATT server, advertising, and managed characteristic patterns
Shiny BluetoothLE client/central operations for scanning, connecting, and communicating with BLE peripherals
Background job scheduling and execution for .NET MAUI (iOS/Android native OS schedulers) and in-process jobs for plain .NET, Linux, macOS, and Blazor WASM using Shiny.Jobs
Guide for generating code that uses Shiny.NET HTTP Transfers for background uploads and downloads on iOS/Android, Windows, Linux, macOS, and Blazor WASM (Service Worker Background Sync)
Core infrastructure, hosting, DI, key-value stores, lifecycle hooks, and platform abstractions for Shiny on .NET MAUI, iOS, and Android
Guide for implementing push notifications in .NET MAUI apps using Shiny.Push (native FCM/APNs) and Shiny.Push.AzureNotificationHubs
| name | shiny-locations |
| description | GPS tracking, geofence monitoring, and motion activity recognition for .NET MAUI, iOS, and Android using Shiny.Locations |
| auto_invoke | true |
| triggers | ["gps","geofence","geofencing","location","position","coordinates","latitude","longitude","distance","tracking","background location","foreground location","GPS delegate","geofence delegate","GpsReading","GpsRequest","GeofenceRegion","IGpsManager","IGeofenceManager","AddGps","AddGeofencing","motion activity","activity recognition","walking","running","cycling","automotive","stationary","IMotionActivityManager","IMotionActivityDelegate","MotionActivityReading","MotionActivityType","MotionActivityConfidence","AddMotionActivity"] |
GPS tracking, geofence monitoring, and motion activity recognition 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 (MAUI), Shiny.Locations.Blazor (Blazor WASM) |
| Namespace | Shiny.Locations |
| Platforms | iOS, Android, Windows, Blazor WebAssembly (foreground GPS only) |
| 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 GPS in Program.cs of a Blazor WebAssembly project. Only foreground GPS
is supported - the browser does not expose background location, geofencing, or
significant-location-change APIs. Background modes on a GpsRequest are silently
treated as foreground.
builder.Services.AddGps();
// or with a foreground-only delegate:
builder.Services.AddGps<MyGpsDelegate>();
Geofencing (AddGeofencing, AddGpsDirectGeofencing) is not available in
Shiny.Locations.Blazor. For region-entry behavior on the web, evaluate regions
server-side from GPS reports and notify the client via Shiny.Push.Blazor.
Register geofencing in MauiProgram.cs:
// Standard geofencing with a delegate
services.AddGeofencing<MyGeofenceDelegate>();
// GPS-direct geofencing (uses realtime GPS - battery intensive)
services.AddGpsDirectGeofencing<MyGeofenceDelegate>();
Register motion activity recognition in MauiProgram.cs:
// Motion activity without a background delegate
services.AddMotionActivity();
// Motion activity with a background delegate
services.AddMotionActivity<MyMotionActivityDelegate>();
Platform support: Motion activity is supported on iOS (CMMotionActivityManager) and Android (Google Play Services Activity Recognition). On Android, Google Play Services must be available — the registration silently no-ops if unavailable. Other platforms (Windows, Blazor) are no-ops.
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. The GpsDelegate supports minimum filters (MinimumDistance, MinimumTime) that use AND logic when both are set, and maximum filters (MaximumDistance, MaximumTime) that use OR logic and always override minimums when crossed.IGeofenceDelegate for geofence enter/exit events.IMotionActivityDelegate for background motion activity processing. The delegate receives MotionActivityReading with Activity (MotionActivityType), Confidence (MotionActivityConfidence), and Timestamp.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. This applies to both IGpsManager and IMotionActivityManager.GeofenceRegion, always provide a unique Identifier string. The SingleUse parameter removes the region after the first trigger. To register a region idempotently, use the TryStartMonitoring(region, replaceIfExists) extension on IGeofenceManager — it only starts monitoring if a region with the same identifier isn't already being monitored, and (when replaceIfExists is true, the default) stops and restarts an existing region so changed position/notification settings take effect. It returns true when the region already existed, false when it was newly added.IMotionActivityManager via constructor injection for motion activity features. Call RequestAccess() before StartListener(), and use WhenReading() for foreground observation or register IMotionActivityDelegate for background processing.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 (AND when both set), MaximumDistance, MaximumTime (OR, overrides minimums) 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.NSMotionUsageDescription to Info.plist when using motion activity recognition.com.google.android.gms.permission.ACTIVITY_RECOGNITION permission and Google Play Services.