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+)

Android enforces a two-step flow:

  1. Request foreground location (ACCESS_FINE_LOCATION + ACCESS_COARSE_LOCATION) and wait for the grant.
  2. 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

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+)

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

  • 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