Sitemap
DeHaat

DeHaat™ is one of the fastest-growing start-ups in the Agri Tech sector and one of the very few companies providing end-to-end solutions and services to the farming community in India. We are building AI-enabled technologies to revolutionise technology in agriculture.

Deprecated requestPermissions()

--

In every application, we generally have the requirement of requesting permissions, and to do so we use the combination of requestPermissions() and onRequestPermissionResult() methods.

requestPermissions() method is used to request multiple permissions at runtime. This function call expects two parameters an array of strings representing the permissions that we want to request and an integer value representing request code which would be used later on for differentiating between the results obtained.

requestPermissions(
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
AppConstant.LOCATION_PERMISSION
)

On other hand overriden onRequestPermissionResult() method is used to capture the results obtained from requestPermissions(). It returns three values first is an integer value which denotes the request code, second is an array of strings representing permissions, and third is an array of integers representing results granted.

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == AppConstant.LOCATION_PERMISSION) {

if (permissions.isEmpty() && grantResults.isEmpty()) {
return
}

if (permissions[0] ==
Manifest.permission.ACCESS_FINE_LOCATION &&
grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
// do something which you want to do
// when permission granted
}
else if (permissions[0] ==
Manifest.permission.ACCESS_FINE_LOCATION &&
grantResults[0] == PackageManager.PERMISSION_DENIED
) {
// if permission denied then check whether never ask
// again is selected or not by making use of
// !ActivityCompat.shouldShowRequestPermissionRationale(
// requireActivity(),
// Manifest.permission.ACCESS_FINE_LOCATION)
}
}
}

All of the above methods work fine but now AndroidStudio has started giving warnings for deprecation of requestPermissions() and the same applies for onRequestPermissionResult() the only difference here is that no warning is given for this method but it’s also deprecated.

So, what’s the solution to remove this deprecation warning?

The solution is to use the new ActivityResultAPI introduced in Android Jetpack which also makes it easier to request runtime permission.

To implement ActivityResultAPI follow the steps below -

1 Make sure that we are using androidx.activity and androidx.fragment libraries in the module’s build.gradle

implementation("androidx.activity:activity-ktx:1.3.1")
implementation("androidx.fragment:fragment-ktx:1.3.6")

2In activity or fragment’s initialization logic, we need to pass ActivityResultContract (represents what type of permission to request single or multiple) and implementation of ActivityResultCallback (defines how the app handles the user’s response to the permission request) into a call to registerForActivityResult(). Keep a reference to the return value of registerForActivityResult(), which is of type ActivityResultLauncher.

ActivityResultContract to use for Single Permission Request -

registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->     // returns boolean representind whether the 
// permission is granted or not
if (isGranted) { // permission granted continue the normal workflow of app Log.i("DEBUG", "permission granted")
} else {
// if permission denied then check whether never ask
// again is selected or not by making use of
// !ActivityCompat.shouldShowRequestPermissionRationale(
// requireActivity(), Manifest.permission.CAMERA)
Log.i("DEBUG", "permission denied")
}
}

ActivityResultContract to use for Multiple Permissions Request -

registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->// returns Map<String, Boolean> where String represents the
// permission requested and boolean represents the
// permission granted or not
// iterate over each entry of map and take action needed for
// each permission requested
permissions.forEach { actionMap ->
when (actionMap.key) {
Manifest.permission.CAMERA -> {
if (actionMap.value) {
// permission granted continue the normal
// workflow of app
Log.i("DEBUG", "permission granted")
} else {
// if permission denied then check whether never
// ask again is selected or not by making use of
// !ActivityCompat.shouldShowRequest
// PermissionRationale(requireActivity(),
// Manifest.permission.CAMERA)
Log.i("DEBUG", "permission denied")
}
}
}
}
}

3To display the system permissions dialog when necessary, call the launch() method on the instance of ActivityResultLauncher that you saved in the previous step.

Get Rohit Gupta’s stories in your inbox

Join Medium for free to get updates from this writer.

launch() to use for Single Permission Request -

requestPermission.launch(Manifest.permission.CAMERA)

launch() to use for Multiple Permissions Request -

requestMultiplePermissions.launch(
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION
)
)

After launch() is called, the system permissions dialog appears. When the user makes a choice, the system asynchronously invokes the ActivityResultCallback where we have provided the implementation of how fragment or activity handles those results.

For single permission request -

class MainActivity : AppCompatActivity() {
private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
// returns boolean representind whether the
// permission is granted or not
if (isGranted) { // permission granted continue the normal workflow of app Log.i("DEBUG", "permission granted")
} else {
// if permission denied then check whether never ask
// again is selected or not by making use of
// !ActivityCompat.shouldShowRequestPermissionRationale(
// requireActivity(), Manifest.permission.CAMERA)
Log.i("DEBUG", "permission denied")
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.button).setOnClickListener {
// call launch with string containing permission to be
// requested to show the system permission dialog
requestPermission.launch(Manifest.permission.CAMERA)
}
}
}

For multiple permissions requests -

class MainActivity : AppCompatActivity() {
private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
// returns Map<String, Boolean> where String represents the
// permission requested and boolean represents the
// permission granted or not
// iterate over each entry of map and take action needed for
// each permission requested
permissions.forEach { actionMap ->
when (actionMap.key) {
Manifest.permission.CAMERA -> {
if (actionMap.value) {
// permission granted continue the normal
// workflow of app
Log.i("DEBUG", "permission granted")
} else {
// if permission denied then check whether never
// ask again is selected or not by making use of
// !ActivityCompat.shouldShowRequest
// PermissionRationale(requireActivity(),
// Manifest.permission.CAMERA)
Log.i("DEBUG", "permission denied")
}
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.button).setOnClickListener {
// call launch with an array of string containing
// permission to be requested to show the system
// permission dialog


requestMultiplePermissions.launch(
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION
)
)
}
}
}

Final Thoughts -

Using requstPermissions() is fine if we have single permission to request at a time but what if we need to request multiple permissions? In that case, things get complicated and there will be additional overhead to maintain those permission codes, and also there will be more code we need to write with this approach. But with the new ActivityResultAPI, the system will handle the request codes so we just need to pass permission that needs to be requested.

Useful Links -https://developer.android.com/training/permissions/requesting

--

--

Rohit Gupta
Rohit Gupta

Written by Rohit Gupta

Software Engineer, Android Developer

DeHaat
DeHaat

Published in DeHaat

DeHaat™ is one of the fastest-growing start-ups in the Agri Tech sector and one of the very few companies providing end-to-end solutions and services to the farming community in India. We are building AI-enabled technologies to revolutionise technology in agriculture.