Biometric fingerprint authentication in Android using AndroidX Biometric library

By | May 12, 2020

Android Fingerprint Authentication

Biometric authentication integration has became very easy in Android with the introduction of AndroidX Biometric library in Android 10 (API level 29). It can achieved only in a few steps. It also provides a default UI for authentication, so there is no need to build any interface for it. Following are the steps to integrate Biometric authentication in Android using Java

Step 1 – Create an new Android application with Java language

Step 2 – Add dependencies for AndroidX Biometric library

implementation 'androidx.biometric:biometric:1.0.1'

Step 3 – Check for Biometric availability in onCreate() method of the activity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    checkBiometricAvailability();
}

private void checkBiometricAvailability() {
    BiometricManager biometricManager = BiometricManager.from(this);

    switch (biometricManager.canAuthenticate()){
        case BiometricManager.BIOMETRIC_SUCCESS:
            getBiometricPrompt().authenticate(getPromptInfo());
            break;
        case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
            Toast.makeText(this, "Biometric device not found on the device", Toast.LENGTH_SHORT).show();
            break;
        case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
            Toast.makeText(this, "Unable to access biometric device. Please try again.", Toast.LENGTH_SHORT).show();
            break;
        case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
            Toast.makeText(this, "No biometrics added in the device", Toast.LENGTH_SHORT).show();
            break;
    }
}

Step 4 – Create a BiometricPrompt object and call BiometricPrompt.authenticate() method if Biometric device found

private BiometricPrompt getBiometricPrompt(){
    Executor executor= ContextCompat.getMainExecutor(this);
    AuthenticationCallback callback=getAuthenticationCallback();
    BiometricPrompt biometricPrompt=new BiometricPrompt(this, executor, callback);
    return biometricPrompt;
}

private AuthenticationCallback getAuthenticationCallback(){
   return new AuthenticationCallback() {
       @Override
       public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
           super.onAuthenticationError(errorCode, errString);
           Toast.makeText(getApplicationContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
       }

       @Override
       public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
           super.onAuthenticationSucceeded(result);
           Toast.makeText(getApplicationContext(), "Authentication succeeded", Toast.LENGTH_SHORT).show();
       }

       @Override
       public void onAuthenticationFailed() {
           super.onAuthenticationFailed();
           Toast.makeText(getApplicationContext(), "Authentication failed", Toast.LENGTH_SHORT).show();
       }
   };
}

private BiometricPrompt.PromptInfo getPromptInfo(){
    BiometricPrompt.PromptInfo promptInfo= new BiometricPrompt.PromptInfo.Builder()
            .setTitle("Login to MyApp")
            .setSubtitle("")
            .setDescription("Use your fingerprint to unlock MyApp")
            .setDeviceCredentialAllowed(true)
            .build();
    return  promptInfo;
}

BiometricPrompt.authenticate() method takes BiometricPrompt.PromptInfo as a parameter. PromptInfo builds UI for Biometric authentication.

AuthenticationCallback handles callbacks after authentication.

Complete Code

package com.example.loginapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricManager;
import androidx.biometric.BiometricPrompt;
import androidx.biometric.BiometricPrompt.AuthenticationCallback;
import androidx.core.content.ContextCompat;

import android.os.Bundle;
import android.widget.Toast;

import java.util.concurrent.Executor;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkBiometricAvailability();
    }

    private void checkBiometricAvailability() {
        BiometricManager biometricManager = BiometricManager.from(this);

        switch (biometricManager.canAuthenticate()){
            case BiometricManager.BIOMETRIC_SUCCESS:
                getBiometricPrompt().authenticate(getPromptInfo());
                break;
            case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
                Toast.makeText(this, "Biometric device not found on the device", Toast.LENGTH_SHORT).show();
                break;
            case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
                Toast.makeText(this, "Unable to access biometric device. Please try again.", Toast.LENGTH_SHORT).show();
                break;
            case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
                Toast.makeText(this, "No biometrics added in the device", Toast.LENGTH_SHORT).show();
                break;
        }
    }

    private BiometricPrompt getBiometricPrompt(){
        Executor executor= ContextCompat.getMainExecutor(this);
        AuthenticationCallback callback=getAuthenticationCallback();
        BiometricPrompt biometricPrompt=new BiometricPrompt(this, executor, callback);
        return biometricPrompt;
    }

    private AuthenticationCallback getAuthenticationCallback(){
        return new AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
                super.onAuthenticationError(errorCode, errString);
                Toast.makeText(getApplicationContext(), "Some error occurred", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                Toast.makeText(getApplicationContext(), "Authentication succeeded", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                Toast.makeText(getApplicationContext(), "Authentication failed", Toast.LENGTH_SHORT).show();
            }
        };
    }

    private BiometricPrompt.PromptInfo getPromptInfo(){
        BiometricPrompt.PromptInfo promptInfo= new BiometricPrompt.PromptInfo.Builder()
                .setTitle("MyApp")
                .setSubtitle("")
                .setDescription("Use your fingerprint to unlock MyApp")
                .setDeviceCredentialAllowed(true)
                .build();
        return  promptInfo;
    }
}

Source Code

Leave a Reply

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