Location Permissions
Geofencing needs location permissions — including background location, since geofence transitions happen while your app is closed. The SDK already declares these in its manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />Your job is requesting them at runtime, in the right order.
The required order (Android 11+, API 30+)
Section titled “The required order (Android 11+, API 30+)”Android enforces a two-step flow:
- Request foreground location (
ACCESS_FINE_LOCATION+ACCESS_COARSE_LOCATION) and wait for the grant. - Only then request background location (
ACCESS_BACKGROUND_LOCATION) — Android takes the user to the app’s settings page (“Allow all the time”) instead of showing a dialog.
Show a priming screen before each step explaining why you need it — this measurably improves opt-in rates and Google may require it during review (Google Play Approval).
Implementation
Section titled “Implementation”class LocationPermissionFragment : Fragment() {
private val requestForegroundLocation = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { results -> val granted = results[Manifest.permission.ACCESS_FINE_LOCATION] == true || results[Manifest.permission.ACCESS_COARSE_LOCATION] == true if (granted) { // Step 2 becomes available — show your background-location priming screen showBackgroundPrimingScreen() } }
private val requestBackgroundLocation = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> if (granted) { /* geofencing fully enabled */ } }
// Step 1 — from your foreground priming screen: private fun requestForeground() { requestForegroundLocation.launch( arrayOf( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, ), ) }
// Step 2 — from your background priming screen, only after step 1 is granted: private fun requestBackground() { requestBackgroundLocation.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION) }}Android 12+ note (API 31+)
Section titled “Android 12+ note (API 31+)”Users can grant only approximate location. Request FINE and COARSE together (as above) and handle the case where only COARSE is granted — geofencing works with reduced accuracy.
Checklist
Section titled “Checklist”- Foreground priming screen → request FINE + COARSE
- Background priming screen (explain “Allow all the time”) → request BACKGROUND
- Handle “approximate only” grants gracefully
- Prepare your Google Play background-location declaration

