Home > Software engineering >  registerForActivityResult execute function as parameter
registerForActivityResult execute function as parameter

Time:01-24

I'm trying to implement a 2 different buttons in a fragment which get location in different ways and them both need to access location permission runtime (in newer versions above M), each have to do another action. I set listener that called WantedAction or WantedAction2 as needed. my minimal basic code to demonstrate my question please:

class MapFragment : Fragment() {
    private val requestPermissionWantedActionLauncher: ActivityResultLauncher<String> =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted)
                wantedAction()
        }

    private val requestPermissionWantedAction2Launcher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted)
                wantedAction2()
        }

    private fun requestLocationPermission(op: ActivityResultLauncher<String>) {
        val permission =
            Manifest.permission.ACCESS_COARSE_LOCATION
        if (shouldShowRequestPermissionRationale(permission)) {
//tell user why this permission is needed
                op.launch(permission)
        } else {
            op.launch(permission)
        }
    }
}

is it possible to send parameter to to requestPermissionWantedActionLauncher or requestPermissionWantedAction2Launcher in order to perform a function call whicl allowed me to combine them please?

thanks in advance

CodePudding user response:

I don't think there's a way to merge them. What you could do to use only a single launcher is create a separate property that tells it what to do when granted.

private var postPermissionGrantedAction: (()->Unit)? = null
    
private val requestPermissionWantedActionLauncher: ActivityResultLauncher<String> =
    registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) postPermissionGrantedAction?.invoke()
    }

private fun requestLocationPermission() {
    val permission = Manifest.permission.ACCESS_COARSE_LOCATION
    if (shouldShowRequestPermissionRationale(permission)) {
        //tell user why this permission is needed
    }
    requestPermissionWantedActionLauncher.launch(permission)
}

Then whichever code calls your requestLocationPermission function should first set the property to the function that should be called, such as:

postLocationPermissionGrantedAction = ::wantedAction
requestLocationPermission()

CodePudding user response:

You could try this:

  • Create a class A that extends ActivityResultCallback<T>
  • Which will have a property B which will be another ActivityResultCallback<T>
  • Use the A one time in registerForActivityResult
  • Each time before launch, assign a lambda to the property(B) of A

This way you can pass whatever lambda you want at each time you launch(no need for flags).

  •  Tags:  
  • Related