-
Notifications
You must be signed in to change notification settings - Fork 72
Location Notifications
Elvin Thudugala edited this page Jul 28, 2025
·
8 revisions
Location-based notifications (Geofencing) allow your app to trigger notifications when users enter or exit specified geographic areas. Available from Version 10.0.1 and above.
- Enter/Exit triggers
- Customizable radius
- Multiple geofence support
- Repeating geofence notifications
- Platform-specific optimizations
- Add permissions to
AndroidManifest.xml
:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- For Android 10+ (API level 29+), add in
MainActivity.cs
:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
- Add keys to
Info.plist
:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open to provide location-based notifications.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when in the background for notifications.</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>fetch</string>
<string>remote-notification</string>
</array>
- Add to
PrivacyInfo.xcprivacy
:
<key>NSPrivacyCollectedDataTypes</key>
<array>
<string>NSPrivacyCollectedDataTypePreciseLocation</string>
</array>
Request necessary permissions at runtime:
public async Task RequestLocationPermissions()
{
try
{
// Check and request notification permissions
if (!await LocalNotificationCenter.Current.AreNotificationsEnabled())
{
await LocalNotificationCenter.Current.RequestNotificationPermission(
new NotificationPermission
{
iOS =
{
LocationAuthorization = iOSLocationAuthorization.Always // or WhenInUse
}
});
}
// Request location permissions
var status = await Permissions.RequestAsync<Permissions.LocationAlways>();
if (status != PermissionStatus.Granted)
{
// Handle permission denial
}
}
catch (Exception ex)
{
Debug.WriteLine($"Permission request failed: {ex.Message}");
}
}
Triggers when user enters the specified area:
var entryNotification = new NotificationRequest
{
NotificationId = 1001,
Title = "Location Alert",
Description = "You have entered the target area",
Geofence =
{
Center =
{
Latitude = -37.003578276665095,
Longitude = 174.78484574983338
},
RadiusInMeters = 100 // 100-meter radius
}
};
await LocalNotificationCenter.Current.Show(entryNotification);
Monitor both entering and leaving an area:
var boundaryNotification = new NotificationRequest
{
NotificationId = 1002,
Title = "Boundary Alert",
Description = "Area boundary crossed",
Geofence =
{
Center =
{
Latitude = -37.003578276665095,
Longitude = 174.78484574983338
},
RadiusInMeters = 100,
NotifyOn = NotificationRequestGeofence.GeofenceNotifyOn.OnEntry |
NotificationRequestGeofence.GeofenceNotifyOn.OnExit
}
};
await LocalNotificationCenter.Current.Show(boundaryNotification);
Continuous location monitoring:
var repeatingGeofence = new NotificationRequest
{
NotificationId = 1003,
Title = "Area Monitor",
Description = "Location boundary activity detected",
Geofence =
{
Center =
{
Latitude = -37.003578276665095,
Longitude = 174.78484574983338
},
RadiusInMeters = 100,
iOS =
{
Repeats = true
},
Android =
{
ExpirationDurationInMilliseconds = -1 // Never expire
}
}
};
await LocalNotificationCenter.Current.Show(repeatingGeofence);
public static class GeofenceSettings
{
// Minimum radius to reduce battery drain
public const int MinimumRadiusMeters = 100;
// Maximum number of concurrent geofences
public const int MaxGeofences = 20;
// Minimum distance between geofences
public const int MinDistanceBetweenFencesMeters = 200;
}
public async Task SafeCreateGeofence(Location location)
{
try
{
// Validate location
if (!IsValidLocation(location))
throw new ArgumentException("Invalid location coordinates");
// Check existing geofences
var pending = await LocalNotificationCenter.Current.GetPendingNotifications();
if (pending.Count >= GeofenceSettings.MaxGeofences)
{
// Remove oldest or handle limit
}
// Create geofence
await CreateGeofenceNotification(location);
}
catch (Exception ex)
{
Debug.WriteLine($"Geofence creation failed: {ex.Message}");
// Handle error appropriately
}
}
- Background location requires explicit user permission
- Battery optimization may affect monitoring
- Location accuracy depends on device settings
- Consider implementing retry logic
- Requires appropriate authorization level
- Background app refresh affects monitoring
- More consistent behavior than Android
- Consider power usage implications
-
Notifications not triggering
- Verify location permissions
- Check location services status
- Confirm geofence radius is appropriate
- Review battery optimization settings
-
Delayed notifications
- Check background refresh settings
- Verify network connectivity
- Review location accuracy settings
- Consider system power mode
-
Battery drain
- Optimize geofence radius
- Limit number of active geofences
- Use appropriate monitoring intervals
- Consider implementing batching
- Clearly explain location usage
- Provide easy opt-out options
- Minimize data collection
- Follow privacy regulations
- Secure location data storage
- Implement proper error handling
- Use appropriate authorization levels
- Regular security audits