Geofencing
Getting Started
Section titled “Getting Started”Geofencing lets your app react when a user enters or exits a geographic area — even when the app is not running. Unlike GPS tracking, geofencing is managed by the operating system and is highly battery efficient, making it ideal for location-triggered background tasks.
Platform Notes
Section titled “Platform Notes”| Feature | Android | iOS | Windows |
|---|---|---|---|
| Max Regions | 60 | 20 | Unlimited |
| Background Support | Yes | Yes | Yes |
| Google Play Fallback | GPS-direct when unavailable | N/A | N/A |
Creating Your Delegate
Section titled “Creating Your Delegate”Implement IGeofenceDelegate to handle geofence enter/exit events. This delegate fires in the background when a boundary is crossed.
public class MyGeofenceDelegate : IGeofenceDelegate{ readonly ILogger<MyGeofenceDelegate> logger;
// Full dependency injection support - treat as a singleton public MyGeofenceDelegate(ILogger<MyGeofenceDelegate> logger) { this.logger = logger; }
public async Task OnStatusChanged(GeofenceState newStatus, GeofenceRegion region) { if (newStatus == GeofenceState.Entered) { this.logger.LogInformation("Entered region: {Region}", region.Identifier); // send a notification, sync data, trigger an action, etc. } else if (newStatus == GeofenceState.Exited) { this.logger.LogInformation("Exited region: {Region}", region.Identifier); } }}Using the Geofence Manager
Section titled “Using the Geofence Manager”Inject IGeofenceManager to manage geofence regions at runtime.
Requesting Permission
Section titled “Requesting Permission”Always request access before starting monitoring:
IGeofenceManager geofenceManager; // injected
var access = await geofenceManager.RequestAccess();if (access != AccessState.Available){ // Handle denied/restricted - show user messaging return;}Starting & Stopping Monitoring
Section titled “Starting & Stopping Monitoring”// Start monitoring a regionawait geofenceManager.StartMonitoring(new GeofenceRegion( "work", new Position(43.6532, -79.3832), // latitude, longitude Distance.FromMeters(200) // radius));
// Stop monitoring a specific regionawait geofenceManager.StopMonitoring("work");
// Stop monitoring all regionsawait geofenceManager.StopAllMonitoring();GeofenceRegion Options
Section titled “GeofenceRegion Options”var region = new GeofenceRegion( Identifier: "coffee-shop", Center: new Position(43.6532, -79.3832), Radius: Distance.FromMeters(100), SingleUse: false, // true = auto-remove after first trigger NotifyOnEntry: true, // fire delegate on enter NotifyOnExit: true // fire delegate on exit);| Parameter | Type | Default | Description |
|---|---|---|---|
Identifier | string | required | Unique ID for the region |
Center | Position | required | Latitude/longitude of the circle center |
Radius | Distance | required | Radius of the circular geofence |
SingleUse | bool | false | Automatically stop monitoring after first trigger |
NotifyOnEntry | bool | true | Fire delegate when entering the region |
NotifyOnExit | bool | true | Fire delegate when exiting the region |
Querying State
Section titled “Querying State”// Get all currently monitored regionsvar regions = geofenceManager.GetMonitorRegions();
// Request the current state of a region (inside or outside)var state = await geofenceManager.RequestState(region);// GeofenceState.Entered, GeofenceState.Exited, or GeofenceState.Unknown
// Check current permission status without promptingvar status = geofenceManager.CurrentStatus;GPS-Direct Geofencing
Section titled “GPS-Direct Geofencing”By default, AddGeofencing uses the native OS geofencing APIs. On Android, if Google Play Services is unavailable, Shiny automatically falls back to GPS-direct geofencing.
You can also explicitly opt into GPS-direct mode:
services.AddGpsDirectGeofencing<MyGeofenceDelegate>();How It Works
Section titled “How It Works”Shiny handles all the platform complexity behind a single API:
- Android: Uses Google Play Services geofencing when available, falls back to GPS-direct otherwise
- iOS 18+: Uses the modern
CLMonitorAPI - iOS < 18: Uses the legacy
CLLocationManagerregion monitoring API - Windows: Uses
Windows.Devices.Geolocation.Geofencing
Monitored regions are automatically persisted and restored on app restart — you don’t need to re-register them.