'How to listen the cancel event from confirmation screen of a biometric prompt?

I'm implementing the latest Biometric prompt in my app and made the Confirmation required true. While doing facial recognition it prompts for user confirmation on successful face verification. If the user clicks on the cancel in the confirmation prompt means I need to execute my function but I don't see any callbacks for that canceled event to override to execute my function. Please help me with this.

That cancel event does not listen in the AuthenticationCallBack. And, I don't see any suggestions or solutions in android docs or forums regarding this issue.

fun initBiometricPrompt(
    activity: AppCompatActivity,
    listener: BiometricAuthListener
): BiometricPrompt {
    val callback = object : BiometricPrompt.AuthenticationCallback() {
        override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
            super.onAuthenticationError(errorCode, errString)
            listener.onBiometricAuthenticationError(errorCode, errString.toString())
        }

        override fun onAuthenticationFailed() {
            super.onAuthenticationFailed()
            Timber.tag("BioMetricAuthentication").e("Authentication failed for an unknown reason")
        }

        override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
            super.onAuthenticationSucceeded(result)
            listener.onBiometricAuthenticationSuccess(result)
        }
    }
    return BiometricPrompt(activity, getMainExecutor(activity), callback)
}

fun showBiometricPrompt(
    @StringRes
    title: Int = R.string.unlock_app
    showSubtitle: Boolean = true,
    activity: AppCompatActivity,
    listener: BiometricAuthListener,
    allowDeviceCredential: Boolean = true
) {
    val promptInfo = BiometricPrompt.PromptInfo.Builder()
        .setTitle(activity.getString(title))
        .setConfirmationRequired(true)
        .setSubtitle((activity.getString(R.string.confirm_your_screen_lock)))
        .apply {
            if (allowDeviceCredential) {
                setDeviceCredentialAllowed(allowDeviceCredential)
            } else {
                setNegativeButtonText(activity.getString(R.string.cancel))
            }
        }.build()
    val biometricPrompt = initBiometricPrompt(activity, listener)
    biometricPrompt.authenticate(promptInfo)
}


Solution 1:[1]

I think what you want to do is check the error code and act according to its value. In your specific case, you want to catch error codes BiometricPrompt.ERROR_USER_CANCELED and BiometricPrompt.ERROR_NEGATIVE_BUTTON.

Example code block:

override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
        super.onAuthenticationError(errorCode, errString) //keep in mind, that this call closes the authentication session
        if (errorCode == BiometricPrompt.ERROR_CANCELED
            || errorCode == BiometricPrompt.ERROR_LOCKOUT
            || errorCode == BiometricPrompt.ERROR_LOCKOUT_PERMANENT
        ) {
            // show a toast and navigate back
        } else if (errorCode == BiometricPrompt.ERROR_USER_CANCELED
            || errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON
        ) {
            // do something else
        }
        ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 N. Park