Fingerprint Authentication using Android Biometric API
Generally, to authenticate into any android application you have to manually enter the username and password. Also, if you forgot the password or username then you have to recover it by going through a series of steps. Now, this authentication method is getting old and applications are switching to Fingerprint Authentication. By adding Fingerprint authentication to your application you do not need to remember the password. Also, no two persons can have the same Fingerprint, so, we need not worry about authenticity.
The Android Biometric Library makes adding these features easy and fun. This library is available back to API level 23 and includes a biometric prompt UI out of the box. It also lets you see if a device supports biometric hardware with a single method call.
Advantages of Using Biometric Authentication
- High security and assurance – Biometric identification provides the answers to “something a person has and is” and helps verify identity
- User Experience – Convenient and fast
- Non-transferrable – Everyone has access to a unique set of biometrics
- Spoof-proof – Biometrics is hard to fake or steal
Let’s Get it Working
In this tutorial, we are going to learn how to add fingerprint authentication using android biometric API to the android application. To really understand the process we will create an app. The App contains a simple view having buttons to authenticate the user with fingerprint and pin. I assume that you have already created a new android project. You can also download or explore code on GitHub.
Step 1) Add androidx.biometric dependency.
Open build.gradle (Module:app) and add the following library dependency within dependencies:
implementation 'androidx.biometric:biometric:1.1.0'
Click Sync now to sync the project so you can use the Biometric API.
Step 2) Update activity_main.xml.
Update the layout file for the MainActivity.kt i.e activity_man.xml and add the below code in the layout file. This code will create two buttons with the label “Biometric Authentication” and “Biometric Authentication + Pin Password”.
<?xml version="1.0" encoding="utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/buttonBiometricAuth" android:layout_width="wrap_content" android:layout_height="wrap_content" android:backgroundTint="@color/colorAccent" android:text="Biometric Authentication" android:textAllCaps="false" android:textColor="@android:color/white" android:textSize="18sp" /> <Button android:id="@+id/buttonBiometricAuthWithPin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="60dp" android:backgroundTint="@color/colorAccent" android:text="Biometric Authentication + Pin Password" android:textAllCaps="false" android:textColor="@android:color/white" android:textSize="18sp" /> </androidx.appcompat.widget.LinearLayoutCompat>
Step 3) Update MainActivity.kt class.
Open class named MainActivity and add below code. Here I have written the code to registered the button’s onClick listeners and functions to add logic for biometric authentication.
initBiometricPrompt() :- function initializes the object for biometric prompt configuration.
Executor that performs tasks on the main thread
BiometricPrompt manages a system-provided biometric prompt
BiometricPrompt.PromptInfo have set of configurable options for how the BiometricPrompt should appear and behave. Here create two object for BiometricPrompt.PromptInfo, one is for only fingerprint authentication and other one is for fingerprint + pin authentication.
isBioMetricSupported() :- function initalizes the object of BiometricManager that provides system information related to biometrics (e.g. fingerprint, face, etc.). This function also checks that if app can authenticate via biometric and print the Biometric Status in Logs.
All the function and objects are created now call BiometricPrompt’s authenticate(BiometricPrompt.PromptInfo info) method and pass prompt info respective object to show the prompt for biometric. Refer to the below images to check how the biometric pop-up will look.
package com.androidtutorialshub.biometric_authentication import android.os.Bundle import android.util.Log import android.widget.Button import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt import androidx.core.content.ContextCompat import java.util.concurrent.Executor class MainActivity : AppCompatActivity() { private lateinit var executor: Executor private lateinit var biometricPrompt: BiometricPrompt private lateinit var promptInfo: BiometricPrompt.PromptInfo private lateinit var promptInfoWithPin: BiometricPrompt.PromptInfo override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // initialize the biometric prompt initBiometricPrompt() // login button on click listener findViewById<Button>(R.id.buttonBiometricAuth).setOnClickListener { // check if biometric supported if (isBioMetricSupported()) { // call authenticate method to show prompt for biometric biometricPrompt.authenticate(promptInfo) } else { // call toast if biometric not supported Toast.makeText(this, "Biometric not supported", Toast.LENGTH_LONG).show() } } // login button on click listener findViewById<Button>(R.id.buttonBiometricAuthWithPin).setOnClickListener { // check if biometric supported if (isBioMetricSupported()) { // call authenticate method to show prompt for biometric + pin biometricPrompt.authenticate(promptInfoWithPin) } else { // call toast if biometric not supported Toast.makeText(this, "Biometric not supported", Toast.LENGTH_LONG).show() } } } /** * method to initialize the biometric prompt configuration */ private fun initBiometricPrompt() { // executor to enqueued tasks on the main thread executor = ContextCompat.getMainExecutor(this) // biometricPrompt to show biometric pop up for authentication biometricPrompt = BiometricPrompt( this, executor, object : BiometricPrompt.AuthenticationCallback() { // authentication error callback override fun onAuthenticationError( errorCode: Int, errString: CharSequence ) { super.onAuthenticationError(errorCode, errString) Toast.makeText( applicationContext, "Authentication error: $errString", Toast.LENGTH_SHORT ).show() } // authentication success callback override fun onAuthenticationSucceeded( result: BiometricPrompt.AuthenticationResult ) { super.onAuthenticationSucceeded(result) Toast.makeText( applicationContext, "Authentication succeeded!", Toast.LENGTH_SHORT ).show() } // authentication failure callback override fun onAuthenticationFailed() { super.onAuthenticationFailed() Toast.makeText( applicationContext, "Authentication failed", Toast.LENGTH_SHORT ).show() } }) // promptInfo to initialize the pop up title, subtitle and negative button text promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle("Login to Android Tutorials Hub") .setSubtitle("Biometric Authentication") .setDescription("Use your fingerprint to access the app") .setNegativeButtonText("Cancel") .build() // promptInfo to initialize the pop up title, subtitle and pin password option enabled promptInfoWithPin = BiometricPrompt.PromptInfo.Builder() .setTitle("Login to Android Tutorials Hub") .setSubtitle("Biometric Authentication + Pin Password") .setDescription("Use your fingerprint or pin to access the app") .setDeviceCredentialAllowed(true) .build() } /** * method to check biometric is supported * * return true/false */ private fun isBioMetricSupported(): Boolean { // biometric manager val biometricManager = BiometricManager.from(this) // check if app can authenticate via biometric when (biometricManager.canAuthenticate()) { // success BiometricManager.BIOMETRIC_SUCCESS -> { Log.e("Biometric Status", "App can authenticate using biometrics.") return true } // error no hardware BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> { Log.e("Biometric Status", "No biometric features available on this device.") return false } // error feature unavailable BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> { Log.e("Biometric Status", "Biometric features are currently unavailable.") return false } // error no biometric enrolled BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> { Log.e( "Biometric Status", "The user hasn't associated any biometric credentials with their account." ) return false } } return false } }
Testing on a Physical Device
With the app is now complete, debug the app on a physical Android device. Click on any of the two buttons to perform biometric authentication. Once the biometric pop-up appears place your fingertip on the fingerprint scanner. If Fingerprint Authentication is successful, you will be shown the Authentication succeeded! message.
Please feel free to comment as well as ask questions. And, yeah! If this post helps you please do share!
Enjoy Coding and Share Knowledge