Issue
How to Manage the permission request code using Navigation Component?
I referred too many website & stack links, none of it worked, still showing deprecated Waring src="https://i.stack.imgur.com/MqV3q.png" alt="enter image description here" />
Google Ref link: https://developer.android.com/training/permissions/requesting#manage-request-code-yourself
Code: :Using below code in fragment
private fun checkMultiplePermissions() {
// check permission first
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// request the permission
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)
} else {
proceedAfterPermission() // has the permission.
}
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
myLog("log", "location code : $requestCode")
when (requestCode) {
100 -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted.
proceedAfterPermission() // permission was granted.
myLog("log", "location granted")
} else {
// permission denied.
myLog("log", "location denied")
}
return
}
}
}
Fragment.kt : full code
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
class FragmentPermission : Fragment() {
private var binding: FragmentPermisionBinding ?= null
// Kotlin
//implementation "androidx.fragment:fragment-ktx:1.3.4"
//https://developer.android.com/training/permissions/requesting#manage-request-code-yourself
// <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
binding = FragmentPermisionBinding.inflate(inflater, container, false)
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// request the permission
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)
} else {
//proceedAfterPermission() // has the permission.
}
return binding!!.root
}
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
myLog("location3", "location code : $requestCode")
when (requestCode) {
100 -> {
// If request is cancelled, the result arrays are empty.
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted.
//proceedAfterPermission() // permission was granted.
myLog("location3", "location granted")
} else {
// permission denied.
myLog("location3", "location denied")
}
return
}
}
}
override fun onDestroyView() {
super.onDestroyView()
binding=null
}
}
Solution
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)
This method is deprecated. use registerForActivityResult(ActivityResultContract, ActivityResultCallback) passing in a ActivityResultContracts.RequestMultiplePermissions object for the ActivityResultContract and handling the result in the callback.
requestPermissions()
API is deprecated, and replaced by registerForActivityResult(ActivityResultContract, ActivityResultCallback)
passing in a ActivityResultContracts.RequestMultiplePermissions
object
for the ActivityResultContract
and handling the result in the callback.
First the activity-ktx build.gradle
module level dependency is needed for the the new API:
implementation 'androidx.activity:activity-ktx:1.3.0-beta01'
Then ActivityResultCallback
callback need to be implemented and passed as a parameter of the registerForActivityResult
. This interface has callbacks that handle the user response to the permission request dialog.
To display the permissions dialog, call the launch()
method on the instance of ActivityResultLauncher
that is returned by the registerForActivityResult
function.
So, create an instance of ActivityResultLauncher
& implement the callback to handle the user response:
private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) { // Do something if permission granted
Log.d("LOG_TAG", "permission granted by the user")
} else { // Do something as the permission is not granted
Log.d("LOG_TAG", "permission denied by the user")
}
}
Then request the permission by using the launch
function:
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
UPDATE
For requesting multiple of permissions at once: You need to pass array of
permission to launch(). ActivityResultCallback
returns a Map<String, Boolean>
with permission as key and its grant status as value:
Then use ActivityResultContracts.RequestMultiplePermissions()
as follows:
private val requestMultiplePermissions =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
permissions.entries.forEach {
Log.e("LOG_TAG", "${it.key} = ${it.value}")
}
}
// Usage:
requestMultiplePermissions.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA
)
)
Applying that on the shared code:
class FragmentPermission : Fragment() {
private var binding: FragmentPermisionBinding ?= null
//...
private val requestPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) { // permission is granted
proceedAfterPermission()
} else {
// handle permission denial
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
binding = FragmentPermisionBinding.inflate(inflater, container, false)
if (ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
proceedAfterPermission()
}
return binding!!.root
}
//.... rest of your code
}
Answered By - Zain
Answer Checked By - Candace Johnson (JavaFixing Volunteer)