Fingerprint Authentication using Android’s Biometric API

Recently, Google released the first stable version of the androidx.biometric library, which allows developers to use the BiometricsPrompt to bring a standardized experience for fingerprint authentication and potentially fewer bugs when the developers implement it from scratch.

In API 28, the FingerprintManager was deprecated and BiometricPrompt came into the picture. It shows a system-provided dialog upon starting the authentication, unlike the FingerprintManager class where the developer had to design the UI for the fingerprint dialog, manage its state, add custom error handling, use 3rd party libraries which can handle fingerprint authentication for you, and more—in other words, a lot

However, the minimum supported version of using BiometricPrompt is Android P, which raises the following question:

Absolutely not! BiometricPrompt has backward compatibility and supports all the devices back to Android 6.0 (API level 23), without the need to write any boilerplate code for the same!

Therefore, in a world where devices may have different types of biometric authentication, it’s much more realistic to have a system-provided authentication dialog since the method may vary by vendor/device. And this is what Google has introduced with BiometricPrompt. 😄

Steps to implement BiometricPrompt Compat:

1. Add the androidx.biometric dependency in the build.gradle file (app-level) :

dependencies {
    def biometric_version = "1.0.0"
    
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ...
    implementation "androidx.biometric:biometric:$biometric_version"
}

2. Add Biometric Permission in the manifest:

3. Create a BiometricPrompt instance:

The BiometricPrompt class has only one constructor, which takes 3 parameters:

  • A reference to the client’s activity.
  • An executor to handle callback events.
  • An object to receive the authentication events.

Let’s create an executor:

Next, we can create an instance of theBiometricPrompt class:

 val biometricPrompt = BiometricPrompt(activity, executor, object : BiometricPrompt.AuthenticationCallback() {

            override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
                super.onAuthenticationError(errorCode, errString)
                if (errorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
                    // user clicked negative/cancel button
                } else {
                    TODO("Called when an unrecoverable error has been encountered and the operation is complete.")
                }
            }

            override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
                super.onAuthenticationSucceeded(result)
                runOnUiThread{
                    [email protected](Intent(activity,NextActivity::class.java))
                }
            }

            override fun onAuthenticationFailed() {
                super.onAuthenticationFailed()
                runOnUiThread{
                    Toast.makeText(activity,"Authentication failed! Please try again.", Toast.LENGTH_SHORT).show()
                }
            }
        })

4. Create a BiometricPrompt.PromptInfo instance:

When we call biometricPrompt.authenticate() to start the authentication, we need to pass an instance of BiometricPrompt.PromptInfo to it. We can create an instance of BiometricPrompt.PromptInfo using BiometricPrompt.PromptInfo.Builder:

val promptInfo = BiometricPrompt.PromptInfo.Builder()
            .setTitle("Authentication prompt!")
            /*Subtitle and description are optional parameters, so, you can skip those parameters.
            .setSubtitle("Set the subtitle to display.")
            .setDescription("Verification required")*/
            .setNegativeButtonText("Cancel")
            .build()

To detect if the user clicked the negative button or not, you can handle the proper error code in the onAuthenticationError() method of AuthenticationCallback(), as shown above.

5. Start authentication

As a last step, you can call the authenticate() method of the BiometricPrompt instance and pass BiometricPrompt.PromptInfo, the instance we built in the previous step:

If you want to cancel the authentication, you can call cancelAuthentication() in the onStop() method of the activity lifecycle callbacks, as shown below:

This is how Biometric Authentication looks like in action:

Conclusion:

Android devs can now use the BiometricPrompt UI provided by the framework (not to be designed by the developer) to ensure consistency and uniformity across all the Android applications, unlike the Fingerprint Manager.

Also, BiometricPrompt supports not only fingerprints but also Face and Iris authentication, providing the much-needed flexibility to users to complete the authentication process using different methods according to their needs.

And with this, you’ve now learned how to use the Biometric API in your apps, congrats! 😄 I hope this article helps you to make some amazing apps using authentication.

You can find the complete code here:

Thanks for reading! If you enjoyed this story, please click the 👏 button and share it to help others find it!

Have feedback? Let’s connect on Twitter.

Fritz

Our team has been at the forefront of Artificial Intelligence and Machine Learning research for more than 15 years and we're using our collective intelligence to help others learn, understand and grow using these new technologies in ethical and sustainable ways.

Comments 0 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *

wix banner square