Skip to main content

Location permission, precision, and background access

Location design starts with purpose: why, when, how precise, and for how long. Request the smallest capability that still makes the feature useful.

Capability levels​

Product needLikely access
Manually choose a cityno location permission
“Stores near me” while screen is openforeground approximate often sufficient
Turn-by-turn navigationforeground precise; foreground service while actively navigating
Alert when arriving at a saved site while app is not visiblecarefully justified background location/geofencing

ACCESS_COARSE_LOCATION represents approximate access. ACCESS_FINE_LOCATION allows precise access, but the user can still choose approximate. Your code must work from actual accuracy, not the permission name you requested.

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Ask progressively​

  1. Let the user enter/search an address without permission.
  2. When they tap Use my location, explain the result.
  3. Request foreground location.
  4. Support approximate results where possible.
  5. Ask for background access only when the user enables a feature that cannot work otherwise, following the platform’s version-specific flow.

Background access is a separate, high-friction capability and Play policy concern. Foreground approximate + background permission still means approximate background location.

Permission is not device readiness​

Even after permission is granted:

  • device location may be disabled;
  • provider/services may be unavailable;
  • no fix may exist yet;
  • the fix may be stale or inaccurate;
  • airplane mode/building/terrain may reduce quality.

Use the location settings APIs where appropriate to explain resolvable settings, and always provide manual/fallback behavior.

Model quality explicitly​

data class LocationSample(
val latitude: Double,
val longitude: Double,
val accuracyMeters: Float,
val measuredAtElapsedRealtimeNanos: Long,
)

fun Location.isUsable(nowElapsedNanos: Long): Boolean {
val ageSeconds = (nowElapsedNanos - elapsedRealtimeNanos) / 1_000_000_000
return accuracy <= 100f && ageSeconds <= 30
}

Use monotonic elapsed time to judge age within a boot session; wall clock can change.

A coordinate is an estimate

Latitude/longitude without accuracy, timestamp, provider/context, and product acceptance criteria is not enough to decide “the user is here.”

✅ / ❌​

  • ❌ Require precise location to show regional weather.
  • ✅ Accept city selection or approximate access.
  • ❌ Request background access together with first foreground request.
  • ✅ Introduce it only when enabling a clear background feature.
  • ❌ Interpret permission granted as a fresh fix.
  • ✅ validate settings, age, and accuracy.
  • ❌ Block the whole app after denial.
  • ✅ keep search/manual entry available.

Sources​

Exercise​

Design permissions for a weather app, ride-hailing app, and family safety app. Explain why each needs no, approximate, precise, or background access and its denial fallback.