You need to actually request the Location permission at runtime (notice the comments in your code stating this).

Updated with Kotlin and background location for API 31 (Android 12):

Starting with API 30 background location must be requested separately. This example is using targetSdk 31 and compileSdk 31. Note that it's possible to bundle the background location request along with the main location request on API 29, however to do that you would need to maintain three separate code paths.
It's easier to just break it out to separate requests for 29 and above.

Be sure to include the latest location services in the app level gradle (18.0.0 at the time of writing):

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

Include the location permissions in the manifest:

<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" />

This is a simplified example that does handle most cases, but in a simplified way. In the case where a user chooses "Don't ask again", on the next app launch it will open up the settings for the user to manually enable the permission.

Full activity code:

import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*


class MainActivity : AppCompatActivity() {

    private var fusedLocationProvider: FusedLocationProviderClient? = null
    private val locationRequest: LocationRequest = LocationRequest.create().apply {
        interval = 30
        fastestInterval = 10
        priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
        maxWaitTime = 60
    }

    private var locationCallback: LocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            val locationList = locationResult.locations
            if (locationList.isNotEmpty()) {
                //The last location in the list is the newest
                val location = locationList.last()
                Toast.makeText(
                    this@MainActivity,
                    "Got Location: " + location.toString(),
                    Toast.LENGTH_LONG
                )
                    .show()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)

        checkLocationPermission()
    }

    override fun onResume() {
        super.onResume()
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED
        ) {

            fusedLocationProvider?.requestLocationUpdates(
                locationRequest,
                locationCallback,
                Looper.getMainLooper()
            )
        }
    }

    override fun onPause() {
        super.onPause()
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            == PackageManager.PERMISSION_GRANTED
        ) {

            fusedLocationProvider?.removeLocationUpdates(locationCallback)
        }
    }

    private fun checkLocationPermission() {
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
            ) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
                AlertDialog.Builder(this)
                    .setTitle("Location Permission Needed")
                    .setMessage("This app needs the Location permission, please accept to use location functionality")
                    .setPositiveButton(
                        "OK"
                    ) { _, _ ->
                        //Prompt the user once explanation has been shown
                        requestLocationPermission()
                    }
                    .create()
                    .show()
            } else {
                // No explanation needed, we can request the permission.
                requestLocationPermission()
            }
        } else {
            checkBackgroundLocation()
        }
    }

    private fun checkBackgroundLocation() {
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_BACKGROUND_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestBackgroundLocationPermission()
        }
    }

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

    private fun requestBackgroundLocationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION
                ),
                MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION
            )
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                MY_PERMISSIONS_REQUEST_LOCATION
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        when (requestCode) {
            MY_PERMISSIONS_REQUEST_LOCATION -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        fusedLocationProvider?.requestLocationUpdates(
                            locationRequest,
                            locationCallback,
                            Looper.getMainLooper()
                        )

                        // Now check background location
                        checkBackgroundLocation()
                    }

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()

                    // Check if we are in a state where the user has denied the permission and
                    // selected Don't ask again
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        )
                    ) {
                        startActivity(
                            Intent(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                                Uri.fromParts("package", this.packageName, null),
                            ),
                        )
                    }
                }
                return
            }
            MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        fusedLocationProvider?.requestLocationUpdates(
                            locationRequest,
                            locationCallback,
                            Looper.getMainLooper()
                        )

                        Toast.makeText(
                            this,
                            "Granted Background Location Permission",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
                }
                return

            }
        }
    }

    companion object {
        private const val MY_PERMISSIONS_REQUEST_LOCATION = 99
        private const val MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION = 66
    }
}

On Android 10 (API 29) it will give the user the choice to grant background location after the initial location request:

On Android 12 (API 31) it will do the same, but the interface is different:

Original Answer in Java:

Here is tested and working code to request the Location permission.

Put this code in the Activity:

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

public boolean checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            new AlertDialog.Builder(this)
                    .setTitle(R.string.title_location_permission)
                    .setMessage(R.string.text_location_permission)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION);
                        }
                    })
                    .create()
                    .show();


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {

                    //Request location updates:
                    locationManager.requestLocationUpdates(provider, 400, 1, this);
                }

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.

            }
            return;
        }

    }
}

Then call the checkLocationPermission() method in onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //.........

    checkLocationPermission();
}

You can then use onResume() and onPause() exactly as it is in the question.

Here is a condensed version that is a bit more clean:

@Override
protected void onResume() {
    super.onResume();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.removeUpdates(this);
    }
}
Answer from Daniel Nugent on Stack Overflow
🌐
Android Developers
developer.android.com › core areas › sensors and location › request location access at runtime
Request location access at runtime | Sensors and location | Android Developers
To handle this potential user behavior, don't request the ACCESS_FINE_LOCATION permission by itself. Instead, request both the ACCESS_FINE_LOCATION permission and the ACCESS_COARSE_LOCATION permission in a single runtime request. If you try to request only ACCESS_FINE_LOCATION, the system ignores the request on some releases of Android 12.
Top answer
1 of 8
191

You need to actually request the Location permission at runtime (notice the comments in your code stating this).

Updated with Kotlin and background location for API 31 (Android 12):

Starting with API 30 background location must be requested separately. This example is using targetSdk 31 and compileSdk 31. Note that it's possible to bundle the background location request along with the main location request on API 29, however to do that you would need to maintain three separate code paths.
It's easier to just break it out to separate requests for 29 and above.

Be sure to include the latest location services in the app level gradle (18.0.0 at the time of writing):

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

Include the location permissions in the manifest:

<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" />

This is a simplified example that does handle most cases, but in a simplified way. In the case where a user chooses "Don't ask again", on the next app launch it will open up the settings for the user to manually enable the permission.

Full activity code:

import android.Manifest
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.location.*


class MainActivity : AppCompatActivity() {

    private var fusedLocationProvider: FusedLocationProviderClient? = null
    private val locationRequest: LocationRequest = LocationRequest.create().apply {
        interval = 30
        fastestInterval = 10
        priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
        maxWaitTime = 60
    }

    private var locationCallback: LocationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            val locationList = locationResult.locations
            if (locationList.isNotEmpty()) {
                //The last location in the list is the newest
                val location = locationList.last()
                Toast.makeText(
                    this@MainActivity,
                    "Got Location: " + location.toString(),
                    Toast.LENGTH_LONG
                )
                    .show()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this)

        checkLocationPermission()
    }

    override fun onResume() {
        super.onResume()
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED
        ) {

            fusedLocationProvider?.requestLocationUpdates(
                locationRequest,
                locationCallback,
                Looper.getMainLooper()
            )
        }
    }

    override fun onPause() {
        super.onPause()
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
            == PackageManager.PERMISSION_GRANTED
        ) {

            fusedLocationProvider?.removeLocationUpdates(locationCallback)
        }
    }

    private fun checkLocationPermission() {
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
            ) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
                AlertDialog.Builder(this)
                    .setTitle("Location Permission Needed")
                    .setMessage("This app needs the Location permission, please accept to use location functionality")
                    .setPositiveButton(
                        "OK"
                    ) { _, _ ->
                        //Prompt the user once explanation has been shown
                        requestLocationPermission()
                    }
                    .create()
                    .show()
            } else {
                // No explanation needed, we can request the permission.
                requestLocationPermission()
            }
        } else {
            checkBackgroundLocation()
        }
    }

    private fun checkBackgroundLocation() {
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_BACKGROUND_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestBackgroundLocationPermission()
        }
    }

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

    private fun requestBackgroundLocationPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION
                ),
                MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION
            )
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                MY_PERMISSIONS_REQUEST_LOCATION
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        when (requestCode) {
            MY_PERMISSIONS_REQUEST_LOCATION -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        fusedLocationProvider?.requestLocationUpdates(
                            locationRequest,
                            locationCallback,
                            Looper.getMainLooper()
                        )

                        // Now check background location
                        checkBackgroundLocation()
                    }

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()

                    // Check if we are in a state where the user has denied the permission and
                    // selected Don't ask again
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        )
                    ) {
                        startActivity(
                            Intent(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                                Uri.fromParts("package", this.packageName, null),
                            ),
                        )
                    }
                }
                return
            }
            MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // location-related task you need to do.
                    if (ContextCompat.checkSelfPermission(
                            this,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) == PackageManager.PERMISSION_GRANTED
                    ) {
                        fusedLocationProvider?.requestLocationUpdates(
                            locationRequest,
                            locationCallback,
                            Looper.getMainLooper()
                        )

                        Toast.makeText(
                            this,
                            "Granted Background Location Permission",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show()
                }
                return

            }
        }
    }

    companion object {
        private const val MY_PERMISSIONS_REQUEST_LOCATION = 99
        private const val MY_PERMISSIONS_REQUEST_BACKGROUND_LOCATION = 66
    }
}

On Android 10 (API 29) it will give the user the choice to grant background location after the initial location request:

On Android 12 (API 31) it will do the same, but the interface is different:

Original Answer in Java:

Here is tested and working code to request the Location permission.

Put this code in the Activity:

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

public boolean checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            new AlertDialog.Builder(this)
                    .setTitle(R.string.title_location_permission)
                    .setMessage(R.string.text_location_permission)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    MY_PERMISSIONS_REQUEST_LOCATION);
                        }
                    })
                    .create()
                    .show();


        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.
                if (ContextCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {

                    //Request location updates:
                    locationManager.requestLocationUpdates(provider, 400, 1, this);
                }

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.

            }
            return;
        }

    }
}

Then call the checkLocationPermission() method in onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //.........

    checkLocationPermission();
}

You can then use onResume() and onPause() exactly as it is in the question.

Here is a condensed version that is a bit more clean:

@Override
protected void onResume() {
    super.onResume();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        locationManager.removeUpdates(this);
    }
}
2 of 8
38

Google has created a library for easy Permissions management. Its called EasyPermissions

Here is a simple example on requesting Location permission using this library.

public class MainActivity extends AppCompatActivity {

    private final int REQUEST_LOCATION_PERMISSION = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        requestLocationPermission();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @AfterPermissionGranted(REQUEST_LOCATION_PERMISSION)
    public void requestLocationPermission() {
        String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION};
        if(EasyPermissions.hasPermissions(this, perms)) {
            Toast.makeText(this, "Permission already granted", Toast.LENGTH_SHORT).show();
        }
        else {
            EasyPermissions.requestPermissions(this, "Please grant the location permission", REQUEST_LOCATION_PERMISSION, perms);
        }
    }
}

@AfterPermissionsGranted(REQUEST_CODE) is used to indicate the method that needs to be executed after a permission request with the request code REQUEST_CODE has been granted.

This above case, the method requestLocationPermission() method is called if the user grants the permission to access location services. So, that method acts as both a callback and a method to request the permissions.

You can implement separate callbacks for permission granted and permission denied as well. It is explained in the github page.

🌐
Notificare
notificare.com › blog › 2024 › 01 › 26 › android-location-permission-guide
Android Location Permission Guide | Notificare
January 26, 2024 - // First, declare your permission launcher private val foregroundLocationPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val granted = permissions.any { it.value } if (granted) { // Permission is granted } } // Request the permission private fun ensureForegroundLocationPermission() { foregroundLocationPermissionLauncher.launch( arrayOf( Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ) ) } This is a very basic example, and we are not handling a particular scenario - when we should show
🌐
Google
developers.google.com › google maps platform › android › maps sdk for android › location data
Location Data | Maps SDK for Android | Google for Developers
Two primary methods for accessing location data are the My Location layer (for simple display) and the Location API (for programmatic access). Essential permissions (ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION) are needed and must be requested ...
🌐
Medium
medium.com › @aman1024 › handling-location-permission-in-android-kotlin-a1bc4c1cd9da
Handling Location runtime permission in Android | Kotlin | by Mobile Alchemist✨ | Medium
May 6, 2025 - Case scenario: The user is trying to access the Location Specific feature but has denied and checked don’t ask again, so he is stuck in the current screen, Now he tries again to access the Location Specific feature, we redirect the User to the SETTING Screen. (where users have to manually grant permission)
🌐
Android Developers
developer.android.com › core areas › sensors and location › request location permissions
Request location permissions | Sensors and location | Android Developers
This document describes the different types of location requirements for Android apps, including foreground and background access, and varying accuracy levels, explaining how to request the appropriate location permissions for each use case.
🌐
TutorialsPoint
tutorialspoint.com › how-to-request-location-permission-at-run-time-in-android
How to request Location permission at run time in Android?
July 1, 2020 - <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.com.sample"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Top answer
1 of 3
16

Ask for permission at runtime to use device current location as below :

if (ActivityCompat.checkSelfPermission(YourActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(YourActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      ActivityCompat.requestPermissions(YourActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
      return;
}else{
  // Write you code here if permission already given.
} 
2 of 3
6

You can do it like this

In Manifest:

<uses-feature android:name="android.hardware.location.gps" />

In Activity where you want this permission request:

ActivityCompat.requestPermissions(this,new String[]
{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

Then get the user answer by using this function :

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
    case 1: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        } else {
            // permission denied, boo! Disable the
            // functionality that depends on this permission.
        }
    return;
    }
        // other 'case' lines to check for other
        // permissions this app might request
}
}

If the user accept it once, then your app will remember it and you won't need to send this DialogBox anymore. Note that the user could disable it later if he decided to. Then before requesting the location, you would have to test if the permission is still granted :

 public boolean checkLocationPermission()
{
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = this.checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
Find elsewhere
🌐
Luasoftware
code.luasoftware.com › tutorials › android › android-request-location-permission
Android Request Location Permission (Kotlin)
.setMessage("Need location permission to get current place") .setPositiveButton(android.R.string.ok) { _, _ -> // ActivityCompat.requestPermissions(activity!!, locationPermissions, REQUEST_LOCATION_PERMISSION) requestPermissions(arrayOf(locationPermission), REQUEST_LOCATION_PERMISSION) } .setNegativeButton(android.R.string.cancel, null) .show() } else { // ActivityCompat.requestPermissions(activity!!, locationPermissions, REQUEST_LOCATION_PERMISSION) requestPermissions(arrayOf(locationPermission), REQUEST_LOCATION_PERMISSION) } } override fun onRequestPermissionsResult( requestCode: Int, permi
🌐
Android Developers
developer.android.com › security › privacy › request runtime permissions
Request runtime permissions | Privacy | Android Developers
If the ContextCompat.checkSelfPermission() method returns PERMISSION_DENIED, call shouldShowRequestPermissionRationale(). If this method returns true, show an educational UI to the user. In this UI, describe why the feature that the user wants to enable needs a particular permission. Additionally, if your app requests a permission related to location, microphone, or camera, consider explaining why your app needs access to this information.
🌐
GitHub
github.com › ParthLotia › LocationPermission
GitHub - ParthLotia/LocationPermission: Location Permission From Android 8 to 13
Here is the Demo for the Location Permission in All Android Versions · I have tested with multiple scenarios , here is the scenario list · Android 8 to 13 tested · If permission given and location not enabled · If permission deny two times (According to the rule changes from Android 11) If permission denied · Programmatically Enabled Location Permission
Author   ParthLotia
🌐
TutorialsPoint
tutorialspoint.com › how-to-request-location-permission-at-runtime-on-kotlin
How to request Location Permission at runtime on Kotlin?
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="app.com.myapplication"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
🌐
Xtremepush
docs.xtremepush.com › docs › android-sdk-location
Android location permissions
The text in this dialog provides more context around the permission request and then allows the user to reopen the permission request again. The setRequestPermissions() method also takes two additional string parameters, which can be used to customise the title and message text of the dialog: ... mPushConnector = new PushConnector.Builder("XPUSH_APP_KEY", "GOOGLE_SENDER_ID") .setEnableLocations(true) .setRequestPermissions(true, "title", "message") .create(this); There is an option in the Android device settings to turn location services on or off.
🌐
GitHub
github.com › Lyokone › flutterlocation › issues › 335
How to 'Disable android permission' (Location, Camera, Storage etc…) programmatically in flutter · Issue #335 · Lyokone/flutterlocation
March 29, 2020 - I have n toggle button in which i am asking for the android manifest permission like Location, Camera, Storage, SMS etc. But now when toggle button off i want to disable the permission may be all at a time or one by one, is that possible in flutter, if yes please guide me how can i achieve this.
Author   Lyokone
🌐
Medium
medium.com › google-developer-experts › exploring-android-q-location-permissions-64d312b0e2e1
Exploring Android Q: Location Permissions | by Joe Birch | Google Developer Experts | Medium
June 5, 2019 - Similarly, requesting either of the two at runtime will also grant the permission. These changes give our users more control over how applications access their location, allowing us to create apps with the users privacy and safety in mind. Any questions about these location changes? Feel free to reach out in the comments! ... Experts on various Google products talking tech. ... Android @ Buffer, Google Developer Expert for Android.
🌐
Thestreamliners
thestreamliners.in › blog › background-location-permission-in-android-11-and-above
Background Location Permission in Android 11 and above
<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" /> I added a simple button in activity_main.xml with id “location_permission”, on click of the button call checkPermission() function:
🌐
Stack Overflow
stackoverflow.com › questions › 42953564 › mock-location-permission-programmatically
android - MOCK_LOCATION_PERMISSION Programmatically - Stack Overflow
I've provide MOCK_LOCATION_PERMISSION in Manifest file. Can we enable or disable the mock location access in android programmatically rather to go in Developer Options manually or by Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS programmatically.
🌐
Google Support
support.google.com › android › answer › 6179507
Manage location permissions for apps - Android Help
Under 'Allowed all the time,' 'Allowed only while in use,' 'Ask every time,' and 'Not allowed,' find the apps that can use your device's location. To change the app's permissions, tap it. Then, choose the location access for the app. Learn about app permissions.
🌐
Medium
medium.com › swlh › request-location-permission-correctly-in-android-11-61afe95a11ad
Request Location Permission Correctly in Android 11. | by Lam Pham | The Startup | Medium
April 26, 2025 - Request Location Permission Correctly in Android 11. Best practices for requesting background location in Android. Since location has now become sensitive data, Android restricts its usage …
🌐
DigitalOcean
digitalocean.com › community › tutorials › android-runtime-permissions-example
Android Runtime Permissions Example | DigitalOcean
August 3, 2022 - Dangerous permissions are grouped into categories that make it easier for the user to understand what they are allowing the application to do. If the user accepts one permission in a group/category they accept the entire group. An example of dangerous permission is android.permission.FINE_LOCATION and android.permission.COARSE_LOCATION.