How to request for permissions on android using the new Results API

Photo by Adrien on Unsplash

How to request for permissions on android using the new Results API

Table of contents

No heading

No headings in the article.

Starting an activity in android and getting a result is a common pattern that has been around for a long time. You start an activity, then listen to the result and do something based on what you get back. For example, you can start an activity to select a document, then get the result (in this case a Uri) and use it however way your app requires. Another way is to use this pattern to request for permissions on certain API levels.

The way the above process was done, the APIs used are the ones that allow you to use startActivityForResult() and onActivityResult() in your UI. However, this API has long since been updated and in this article, we will see how to use the new API to request permissions on android.

Requesting a single permission

First off, using this new API requires the at least following versions of the activity.

implementation "androidx.activity:activity-ktx:1.2.0-alpha04"

Once you have this, you need to pass a ActivityResultCallback inside your activity. The callback is the one that finally gets the result from the other activity. In our case, this would be the result of what the user selected once prompted for the permission. In order to display the dialog to the use, the callback has a handy launch() method, which you can trigger anywhere you wish. The following is what an implementation would look like.

class MyActivity : AppCompatActivity() {
    private val requestLocationPermission =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) { isPermissionGranted ->
            if (isPermissionGranted) {
                // You have the permissions
            } else {
                // You do NOT have the permissions
            }
        }

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

        button.setOnClickListener {
            requestLocationPermission.launch(Manifest.permission.ACCESS_COARSE_LOCATION)
        }
    }
}

What about multiple permissions?

The code for multiple permissions looks more or less the same although there are a few changes namely:

  1. The contract used is now going to be ActivityResultContracts.RequestMultiplePermissions()
  2. The result obtained in the lambda is now going to be a map
  3. The call to launch() now takes it an array of all your permissions

The following is how your code would look like.

class MyActivity : AppCompatActivity() {
    private val requestMultiplePermissions =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->

            val isAnyPermissionDenied = permissions.entries.any { !it.value }

            if (!isAnyPermissionDenied) {
                // You have ALL the permission
            } else {
                // There is at least one permission denied
            }
        }

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

        button.setOnClickListener {
            requestMultiplePermissions.launch(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION))
        }
    }
}

Conclusion As you can see, the new API greatly simplifies how activity results are handled in Android. For starters, you do not need to check that codes match what you used to start an activity for result. Each callback automatically handles this for you. If you wish to read more about the new API, check this out.

PS Let us connect on Twitter , GitHub , and Linkedin . You can follow me on Hashnode as well and let us build awesome things together.