Android Request Location Permission (Kotlin)

November 22, 2019

Edit AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>

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

    ...
</manifest>

NOTE: If you use library like Places SDK for Android, you don’t need to declare the above permission as the library declares all permissions it uses in its manifest.

class HomeFragment: Fragment() {
    companion object {
        private const val REQUEST_LOCATION_PERMISSION = 1
    }

    // private val locationPermissions = arrayOf(ACCESS_FINE_LOCATION)
    private val locationPermission = ACCESS_FINE_LOCATION

    private fun findCurrentPlace() {
        val placesClient = Places.createClient(context!!)

        val placeFields = listOf(Place.Field.NAME)
        val request = FindCurrentPlaceRequest.newInstance(placeFields)
        if (checkLocationPermission()) {
            val placeResponse = placesClient.findCurrentPlace(request)
            placeResponse.addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    val response = task.result
                    response?.placeLikelihoods?.forEach {
                        Timber.d("${it.place.name}, score=${it.likelihood}")
                    }
                }
                else {
                    Timber.e(task.exception, "placesClient.findCurrentPlace failed")
                }
            }
        }
        else {
            requestLocationPermission()
        }
    }

    private fun checkLocationPermission(): Boolean {
        /*
        locationPermissions.forEach {
            if (ContextCompat.checkSelfPermission(context!!, it) != PackageManager.PERMISSION_GRANTED) {
                return false
            }
        }
        return true
         */
        return (ContextCompat.checkSelfPermission(context!!, locationPermission) == PackageManager.PERMISSION_GRANTED)
    }

    private fun requestLocationPermission() {
        // optional implementation of shouldShowRequestPermissionRationale
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity!!, locationPermission)) {
            AlertDialog.Builder(context!!)
                .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,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_LOCATION_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                findCurrentPlace()
            } else {
                Timber.d("Location permission denied")

                val isNeverAskAgain = !ActivityCompat.shouldShowRequestPermissionRationale(
                        activity!!,
                        locationPermission)

                if (isNeverAskAgain) {
                    Snackbar.make(list, "Location Permission required", Snackbar.LENGTH_LONG)
                        .setAction("Settings") {
                            Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:${activity!!.packageName}")).apply {
                                addCategory(Intent.CATEGORY_DEFAULT)
                                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                startActivity(this)
                            }
                        }
                        .show()
                }
                else {
                    Timber.d("Location permission denied")
                }
            }
        }
    }
}

NOTE: You might want to use EasyPermissions

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.