Search code examples
androidkotlinlambdaandroid-permissions

Where does this "isGranted" variable come from when getting permissions?


I'm only a beginner Kotlin programmer, with some experience in other languages but nothing particularly advanced. I'm struggling to understand what exactly is happening in this code, which comes from an Android course but matches this article on requesting permissions from the user. I understand the overall effect, but one part is really tripping me up.

private val cameraResultLauncher = registerForActivityResult(
            ActivityResultContracts.RequestPermission()) {
                isGranted ->
                if(isGranted) {
                    Toast.makeText(this,
                        "Permission granted for camera", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this,
                        "Permission denied for camera", Toast.LENGTH_SHORT).show()
                }
            }

Where exactly is the value of the variable isGranted coming from? I understand that we call registerForActivityResult, passing it the result of ActivityResultContracts.RequestPermission(), and then assign all that to cameraResultLauncher... right? But somehow data from that is being used in the lambda expression that follows, and is being assigned to the parameter isGranted? I don't understand why this code is only executed at the end of a cameraResultLauncher.launch() call, either. Is the lambda expression stored as part of the variable itself? Does calling launch() trigger it, or calling the variable at all?

I've tried to research this myself, but I'm not sure of the name for this structure, and most of what I've found regarding advanced use of lambda expressions goes way over my head. If someone could explain or at least provide links explaining the flow of information in this structure, I would be very grateful.


Solution

  • It comes from ActivityResultCallback which is the second argument of function registerForActivityResult . Check the function definition ..

     public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull ActivityResultContract<I, O> contract,
            @NonNull ActivityResultCallback<O> callback) {
        return registerForActivityResult(contract, mActivityResultRegistry, callback);
    }
    

    Since its a single method interface it can be converted to lambda thats called SAM conversion and also its the last parameter so it can be moved outside of braces .. that lambda is equivalent to code below for WHICH IDE will give u A hint to convert this to lambda . hence the shorter variant ..

    val cameraResultLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission(),
        object : ActivityResultCallback<Boolean> {
            override fun onActivityResult(isGranted: Boolean) {
                if(isGranted) {
                    // Granted
                } else {
                    // Denied
                }
            }
        })