---
name: maui-geolocation
description: >
  Add geolocation capabilities to .NET MAUI apps using Microsoft.Maui.Devices.Sensors.
  Covers one-shot and continuous location, platform permissions (Android, iOS, macOS, Windows),
  accuracy levels, CancellationToken usage, mock-location detection, and a DI-friendly service wrapper.
  USE FOR: "geolocation", "GPS location", "get current location", "location permission",
  "continuous location", "location tracking", "GeolocationRequest", "mock location",
  "latitude longitude MAUI".
  DO NOT USE FOR: displaying locations on a map (use maui-maps),
  general permission handling (use maui-permissions), or geocoding addresses (use maui-maps).
---

# .NET MAUI Geolocation

## Critical: Always Pass a CancellationToken

`GetLocationAsync` can hang indefinitely if GPS is off, the device is indoors,
or permissions are in a pending state. Always set a timeout.

```csharp
// ❌ Hangs forever if no GPS fix is available
var location = await Geolocation.Default.GetLocationAsync(
    new GeolocationRequest(GeolocationAccuracy.High));

// ✅ Times out after 30 seconds
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var location = await Geolocation.Default.GetLocationAsync(
    new GeolocationRequest(GeolocationAccuracy.High), cts.Token);
```

---

## Accuracy vs. Battery Trade-off

Use the **lowest accuracy** that satisfies your feature. Higher accuracy
drains battery significantly faster — especially on Android.

| Use case | Recommended accuracy |
|---|---|
| City-level / weather | `Lowest` or `Low` |
| Nearby search / store finder | `Medium` |
| Turn-by-turn navigation | `High` or `Best` |

---

## Platform Gotchas

### iOS 14 reduced accuracy

Users can grant "approximate" location (accuracy > 1 km). Your app receives
a location, but it may be useless for precision features.

- Check `location.Accuracy` — values > 100 m likely indicate reduced precision.
- Use `GeolocationRequest.RequestFullAccuracy` with a key matching
  `NSLocationTemporaryUsageDescriptionDictionary` in `Info.plist` to
  prompt for full accuracy.

### Android: mock locations in security-sensitive flows

```csharp
// ⚠️ Always check in security-sensitive flows (e.g., geofence, check-in)
if (location.IsFromMockProvider)
{
    // Reject — user is spoofing location
}
```

### Android: `Altitude` 0.0 is not sea level

Some Android devices return `0.0` for `Altitude` when the GPS has no
barometric sensor. Treat `0.0` as **"unknown"**, not sea level.

### Android 10+: background location requires separate permission

`ACCESS_BACKGROUND_LOCATION` must be requested **separately** from foreground
permissions and triggers a distinct system dialog. Requesting it together with
foreground permissions causes both to be denied on some devices.

### `GetLastKnownLocationAsync` returns `null`

This is expected on first boot or after a location-data reset. Always fall
back to `GetLocationAsync`:

```csharp
// ✅ Cache-first with fresh fallback
var location = await geolocation.GetLastKnownLocationAsync();
if (location is null || location.Timestamp < DateTimeOffset.UtcNow.AddMinutes(-5))
{
    location = await geolocation.GetLocationAsync(
        new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10)), ct);
}
```

### Permissions must be requested before any geolocation call

Call `Permissions.RequestAsync<Permissions.LocationWhenInUse>()` first, or
catch `PermissionException`. Calling `GetLocationAsync` without permission
throws on some platforms and returns `null` on others — inconsistent
behaviour across platforms.

---

## Continuous Listening: Don't Forget to Unsubscribe

Failing to remove the `LocationChanged` handler when stopping causes
continued GPS usage and battery drain.

```csharp
// ❌ Forgetting to unsubscribe — GPS stays active
public void StopTracking()
{
    Geolocation.Default.StopListeningForeground();
    // LocationChanged handler still fires!
}

// ✅ Always remove the event handler
public void StopTracking()
{
    Geolocation.Default.StopListeningForeground();
    Geolocation.Default.LocationChanged -= OnLocationChanged;
}
```

---

## Checklist

- [ ] `CancellationToken` passed to every `GetLocationAsync` call
- [ ] Accuracy level matched to feature need (not blindly set to `Best`)
- [ ] `GetLastKnownLocationAsync` null-check with `GetLocationAsync` fallback
- [ ] Runtime permissions requested before first geolocation call
- [ ] `LocationChanged` handler removed when stopping continuous listening
- [ ] Android: `ACCESS_BACKGROUND_LOCATION` requested separately (if needed)
- [ ] iOS: `NSLocationTemporaryUsageDescriptionDictionary` added for full-accuracy prompt
- [ ] Android: `IsFromMockProvider` checked in security-sensitive flows


---
Source attribution: davidortinau
Original project: https://github.com/davidortinau/maui-skills/blob/79bb4bfd8f671ed0dd97bdf92a36430928e8d984/plugins/maui-skills/skills/maui-geolocation/SKILL.md
License: MIT
License information: https://opensource.org/license/mit
Original upstream instructions; downloaded from Mega AI Hub.

## Upstream license notice

MIT License

Copyright (c) 2026 David Ortinau

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



# Mega AI Hub resource metadata

Creator / publisher: davidortinau
Original project: https://github.com/davidortinau/maui-skills/blob/79bb4bfd8f671ed0dd97bdf92a36430928e8d984/plugins/maui-skills/skills/maui-geolocation/SKILL.md
Attribution basis: Source repository record

Fields of work: Development & Engineering
Roles: Backend Developer, Mobile Developer
Specialties: Frontend, Git, Mobile
Tools: Tool not specified
Country applicability: Country not specified
Classification basis: Source catalog labels
Instruction SHA-256: 1db6d2a29c750eb0b3e76a3113202fcf302d3b39bbc772856b6347c3e2c5341d
