Complete Guide to Runtime Location Permission Requests in Android

Nov 23, 2025 · Programming · 15 views · 7.8

Keywords: Android Runtime Permissions | Location Permission Request | FusedLocationProvider

Abstract: This article provides an in-depth exploration of runtime location permission implementation for Android 6.0 and above. Through analysis of common error cases, it details permission checking, request workflows, user interaction handling, and special requirements for background location access. The guide offers modern implementation using FusedLocationProviderClient and compares permission handling differences across Android versions.

Runtime Permission Mechanism Overview

Starting from Android 6.0 (API level 23), Google introduced the runtime permission model, requiring applications to explicitly request user authorization at runtime when accessing sensitive permissions such as location information. This mechanism significantly enhances user control over personal data while imposing higher technical requirements on developers.

Common Issue Analysis

In the original code, while the developer correctly declared permissions and added <uses-permission> tags in the manifest file, they failed to implement the runtime permission request logic. The permission checks in the code only returned TODO comments, causing the permission request flow to never execute. This is a typical reason why location services fail to work properly on Android 6.0+ devices.

Permission Declaration Configuration

Correctly declaring location permissions in AndroidManifest.xml is the foundational prerequisite:

<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 29) and above, background location permission requires separate declaration and request, representing an important evolution in the permission model.

Modern Location Service Implementation

Using Google Play Services' Fused Location Provider API is recommended, as it provides more efficient and power-optimized location acquisition. First, add the dependency in build.gradle:

implementation "com.google.android.gms:play-services-location:18.0.0"

Permission Request Flow Design

A complete permission request flow should include the following key steps:

private fun checkLocationPermission() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
        != PackageManager.PERMISSION_GRANTED) {
        
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
            Manifest.permission.ACCESS_FINE_LOCATION)) {
            
            showPermissionExplanation()
        } else {
            requestLocationPermission()
        }
    } else {
        checkBackgroundLocation()
    }
}

User Interaction and Explanation

When users have previously denied permission requests, an explanatory dialog should be displayed to clarify the necessity of the permission:

private fun showPermissionExplanation() {
    AlertDialog.Builder(this)
        .setTitle("Location Permission Needed")
        .setMessage("This app needs location permission to provide positioning services")
        .setPositiveButton("OK") { _, _ ->
            requestLocationPermission()
        }
        .create()
        .show()
}

Permission Request Execution

The actual permission request is implemented through the ActivityCompat.requestPermissions method:

private fun requestLocationPermission() {
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
        MY_PERMISSIONS_REQUEST_LOCATION
    )
}

Permission Result Handling

Override the onRequestPermissionsResult method to handle user responses:

override fun onRequestPermissionsResult(requestCode: Int, 
                                      permissions: Array<String>, 
                                      grantResults: IntArray) {
    when (requestCode) {
        MY_PERMISSIONS_REQUEST_LOCATION -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startLocationUpdates()
                checkBackgroundLocation()
            } else {
                handlePermissionDenied()
            }
        }
    }
}

Background Location Permission Handling

Android 10+ introduced independent management of background location permissions:

private fun checkBackgroundLocation() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
        ActivityCompat.checkSelfPermission(this, 
            Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        
        requestBackgroundLocationPermission()
    }
}

Location Update Management

After obtaining permissions, start the location listening service:

private fun startLocationUpdates() {
    val locationRequest = LocationRequest.create().apply {
        interval = 30000
        fastestInterval = 10000
        priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
        maxWaitTime = 60000
    }
    
    fusedLocationProvider?.requestLocationUpdates(
        locationRequest,
        locationCallback,
        Looper.getMainLooper()
    )
}

Lifecycle Management

Manage location updates in onResume and onPause to optimize battery usage:

override fun onResume() {
    super.onResume()
    if (hasLocationPermission()) {
        startLocationUpdates()
    }
}

override fun onPause() {
    super.onPause()
    if (hasLocationPermission()) {
        stopLocationUpdates()
    }
}

Permission Denial Handling Strategy

When users select "Don't ask again", guide them to the system settings page:

private fun handlePermissionDenied() {
    if (!ActivityCompat.shouldShowRequestPermissionRationale(this, 
        Manifest.permission.ACCESS_FINE_LOCATION)) {
        
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            data = Uri.fromParts("package", packageName, null)
        }
        startActivity(intent)
    }
}

Version Compatibility Considerations

Adopt differentiated strategies for different Android versions:

Best Practices Summary

Implementing robust location permission management should follow these principles: progressive permission requests, clear user explanations, graceful denial handling, and complete lifecycle management. By adopting Fused Location Provider and modern permission handling patterns, developers can build location service applications that comply with platform specifications while providing excellent user experience.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.