3

I'm calling StartIntentSenderForResult() but it doesn't get called.

    val authResult = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartIntentSenderForResult()
    ) {
        Log.d("appDebug", "called!!!") // not get called
    }

    oneTapClient.beginSignIn(signUpRequest)
        .addOnSuccessListener(activity) { result ->
            try {
                // Calling here for result
                authResult.launch(
                    IntentSenderRequest
                        .Builder(result.pendingIntent.intentSender)
                        .build()
                )
            } catch (e: IntentSender.SendIntentException) {
                Log.d("appDebug", "CATCH : ${e.localizedMessage}")
            }
        }
        .addOnFailureListener(activity) { e ->
            Log.d("appDebug", "FAILED : ${e.localizedMessage}")
        }

2 Answers2

0

If someone having same issue then just use this composable instead of rememberLauncherForActivityResult().

Thanks to @Róbert Nagy Ref: https://stackoverflow.com/a/65323208/15301088

I removed some deprecated codes from original post now it works fine for me.

@Composable
fun <I, O> registerForActivityResult(
    contract: ActivityResultContract<I, O>,
    onResult: (O) -> Unit
): ActivityResultLauncher<I> {
    val owner = LocalContext.current as ActivityResultRegistryOwner
    val activityResultRegistry = owner.activityResultRegistry

    // Tracking current onResult listener
    val currentOnResult = rememberUpdatedState(onResult)

    // Only need to be unique and consistent across configuration changes.
    val key = remember { UUID.randomUUID().toString() }

    DisposableEffect(activityResultRegistry, key, contract) {
       onDispose {
           realLauncher.unregister()
       }
   }

   return realLauncher
}

for e.g.

val registerActivityResult = registerForActivityResult(
    contract = ActivityResultContracts.StartIntentSenderForResult()
) {
    // handle your response
}

// just call launch and pass the contract
registerActivityResult.launch(/*Your Contract*/)
0

To use a regular intent, or to convert it to a pending intent, which is what you need to get to use rememberLauncherForActivityResult:

val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartIntentSenderForResult()) { activityResult ->
    if (activityResult.resultCode == RESULT_OK) {
        loginViewModel.showBiometriPrompt(true)
        loginViewModel.showUnlockFingerprint(false)
    }
    else {
        Timber.d("Unlock denied")
    }
}

and then wrap your intent in a pending intent:

if (showFingerprintUnlock) {
    LocalContext.current.getActivity<MainActivity>()?.let {
        val keyguardManager: KeyguardManager = it.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        val intent = keyguardManager.createConfirmDeviceCredentialIntent(
            stringResource(id = R.string.you_must_reauthenticate_your_fingerprint), stringResource(
                id = R.string.too_many_times_disabled_biometrics
            ))
        val mutablePendingIntent = PendingIntent.getActivity(
            it,
            ACTIVITY_UNLOCK,
            intent,
            PendingIntent.FLAG_MUTABLE
        )
        val intentSenderRequest = IntentSenderRequest.Builder(mutablePendingIntent.intentSender).build()
        launcher.launch(intentSenderRequest)
     }
}
Kristy Welsh
  • 7,828
  • 12
  • 64
  • 106