Search code examples
androidkotlinandroid-biometric-promptandroid-biometric

Android BiometricPrompt: Face authentication is ignored when device credential is allowed


I integrate Biometric authentication using Fingerprint, Face, and device credentials (PIN/PASSCODE/PATTERN). But I got the issue with face authentication when using device credentials. it happens on some devices.

When I integrate Fingerprint, Face, and device credentials. The biometric popup just only detects Fingerprint and has a button to move to device credentials. The option for face authentication should be displayed.

If I integrate Face and device credentials. The biometric popup is ignored, and its moves to the screen for input device credentials automatically. In this case, the popup should be displayed and user can authenticate with their face or move to use device credentials with a button if they want.

If I integrate fingerprint or face or both without device credentials. Everything works well.

This is my code with device credentials:

@Suppress("DEPRECATION")
    fun createPromptInfo(activity: AppCompatActivity): BiometricPrompt.PromptInfo =
        BiometricPrompt.PromptInfo.Builder().apply {
            setTitle(activity.getString(R.string.title)
            setSubtitle(activity.getString(R.string.subtitle))
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                setAllowedAuthenticators(
                    BiometricManager.Authenticators.BIOMETRIC_STRONG or
                        BiometricManager.Authenticators.BIOMETRIC_WEAK or
                        BiometricManager.Authenticators.DEVICE_CREDENTIAL
                )
            } else {
                setDeviceCredentialAllowed(true)
            }
            setConfirmationRequired(false)
        }.build()

I face this issue on Samsung A30s and Samsung A31 (both's OS is Android 10). But when I test on Samsung M33 (Android 12), everything is good, it doesn't have this issue.


Solution

  • Most probably you do not fully understand BiometricPrompt documentation and Android ecosystem. You tried to use androidx.biometric library, which handle most of cases for "regular" biometric authentication.

    The issue is not in BiometricPrompt API, but in the device.

    In your case, the device manufacturer has implemented biometric authentication via fingerprint/face/iris, but "forgot" to provide access to this implementation for third-party developers. Therefore, preinstalled (system) applications developed by the device manufacturer can use biometrics (for example, Keyguard/Device Unlock), while banking applications, password managers, and other third-party applications - cannot.

    FaceUnlock slowly started to be accessible exactly on Android 12 and newer, dependent (again) from the device manufacturer. In the case of devices with older OS versions, BiometricManager.Authenticators.DEVICE_CREDENTIAL in case when biometric not accesible/not enrolled, allows the user to authenticate itself and unlock the application etc.

    So technicaly, library works properly and correct on all devices that you test.

    PS: Some of the vendors (like Huawei) provide API for 3-rd party developers, and you can implement own unlock functionality.

    And last, you can use exists libs, that already implement authentification, even if built-in API do not provide FaceUnlock functionality.