In this tutorial, I will show you how you can integrate Fingerprint Authentication in your Android application. You can use this authentication before in-app payments or before accessing an API etc. It helps us secure features of our Application that should be asking for authentication before getting used. Here, we will see how to get our fingerprint authentication done and after the user is authenticated we are showing a Toast to make this project simple for understanding, but you can do anything you wish, like sending the user to another activity etc. We will develop this App in simple 5 Steps! In the case of any problem/queries, you can comment in the comment section below.

Output: –

Download Project – [media-downloader media_id=”1311″]

Download APK – [media-downloader media_id=”1313″]

Wants to Learn Advanced Android Application development from scratch- Beyond Basics

Creating New Proje the t  – Fingerprint

Step 1: – Creating Project

Open your Android Studio -> Create a new project (min SDK should be 23)-> Choose BlankActivity > Finish

Step 2: Creating activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:background="#D4D4D4">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:srcCompat="@drawable/fingerprint" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageView"
        android:text="Place your fingerprint on the Sensor!"
        android:textAlignment="center"
        android:textSize="20dp"
        android:textStyle="bold" />
</LinearLayout>

We have kept the Layout minimalistic for your better understanding. Since the app requires Fingerprint Authentication. so it is not dependent on any View of your Layout

Step 3: Creating MainActivity.java

Before executing the code we need to verify the Android version(should be at least Android M). then we will check if the device as a Fingerprint Sensor.  when all these checks are done we gain access to the Android Keystore. Here the cryptographic keys are stored in a way that it becomes difficult to extract from the device. generatekey() is used to access Android Keystore and generate the encryption key.We generate the key using

keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");

To initialize the key generator we will use keyGenerator.init(new…) We will initialize then a cipher to create an encrypted CryptoObject instance, which will further be used to instantiate FingerprintManager. FingerprintManager is a class that coordinated access to the fingerprint hardware.

Final MainActivity.java will look like this

package com.mytrendin.fingerprint;

import android.Manifest;
import android.app.KeyguardManager;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.Bundle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class MainActivity extends AppCompatActivity {

    private static final String KEY_NAME = "yourKey";
    private Cipher cipher;
    private KeyStore keyStore;
    private KeyGenerator keyGenerator;
    private FingerprintManager.CryptoObject cryptoObject;
    private FingerprintManager fingerprintManager;
    private KeyguardManager keyguardManager;

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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
            fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

            if (!fingerprintManager.isHardwareDetected()) {
                Toast.makeText(getApplicationContext(), "Your device doesn't support fingerprint authentication", Toast.LENGTH_SHORT).show();
            }
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(getApplicationContext(), "Please enable the fingerprint permission", Toast.LENGTH_SHORT).show();
            }

            if (!fingerprintManager.hasEnrolledFingerprints()) {
                Toast.makeText(getApplicationContext(), "Your Device has no registered Fingerprints! Please register atleast one in your Device settings", Toast.LENGTH_LONG).show();
            }

            //Check that the lockscreen is secured//
            if (!keyguardManager.isKeyguardSecure()) {
                Toast.makeText(getApplicationContext(), "Please enable lockscreen security in your device's Settings", Toast.LENGTH_LONG).show();

            } else {
                try {
                    generateKey();
                } catch (FingerprintException e) {
                    e.printStackTrace();
                }

                if (initCipher()) {
                    cryptoObject = new FingerprintManager.CryptoObject(cipher);
                    FingerprintHelper helper = new FingerprintHelper(this);
                    helper.startAuth(fingerprintManager, cryptoObject);
                }
            }
        }
    }

    private void generateKey() throws FingerprintException {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
            keyStore.load(null);
            keyGenerator.init(new

                    KeyGenParameterSpec.Builder(KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)
                    .setEncryptionPaddings(
                            KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());

            keyGenerator.generateKey();
        } catch (KeyStoreException
                | NoSuchAlgorithmException
                | NoSuchProviderException
                | InvalidAlgorithmParameterException
                | CertificateException
                | IOException exc) {
            exc.printStackTrace();
            throw new FingerprintException(exc);
        }
    }

    public boolean initCipher() {
        try {
            cipher = Cipher.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES + "/"
                            + KeyProperties.BLOCK_MODE_CBC + "/"
                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        } catch (NoSuchAlgorithmException |
                NoSuchPaddingException e) {
            throw new RuntimeException("Failed to get Cipher", e);
        }
        try {
            keyStore.load(null);
            SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
                    null);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            return false;
        } catch (KeyStoreException | CertificateException
                | UnrecoverableKeyException | IOException
                | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }
    }

    private class FingerprintException extends Exception {
        public FingerprintException(Exception e) {
            super(e);
        }
    }
}

Related:

Android Motion Sensor using SensorManager and SensorEventListener

Adding Admob in Android

How to use Android ActiveAndroid Library

Creating App Introduction(tour) slider using AppIntro Library.

Parsing JSON using Moshi Library in Android

Step 4: Creating FingerprintHelper.java

startAuth() is responsible for starting fingerprint authentication process. in case any fatal error occurs then onAuthenticationError will be called.

If authentication process failed then onauthenticationFailed() will be called where we raise a toast telling the user about the failure. The object of  CancellationSignal class will help other apps use the fingerprint sensor when our app goes into the background. without this, other apps will be unable to access the sensor. onAuthenticationSucceeded() is called when fingerprint detected is successfully matched with the fingerprint stored in user’s device.You may get more information from Google’s official site

Final FingerprintHandler.java will look like this

package com.mytrendin.fingerprint;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;

@TargetApi(Build.VERSION_CODES.M)

public class FingerprintHelper extends FingerprintManager.AuthenticationCallback {

    private CancellationSignal cancellationSignal;
    private Context context;

    public FingerprintHelper(Context mContext) {
        context = mContext;
    }

    public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {

        cancellationSignal = new CancellationSignal();
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
    }

    @Override
    public void onAuthenticationError(int errMsgId, CharSequence errString) {
        Toast.makeText(context, "Authentication error\n" + errString, Toast.LENGTH_SHORT).show();
    }

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

    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
        Toast.makeText(context, "Authentication help\n" + helpString, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onAuthenticationSucceeded(
            FingerprintManager.AuthenticationResult result) {
        Toast.makeText(context, "You have Been Successfully Logged in!", Toast.LENGTH_SHORT).show();

    }

}

Step 5: Adding Permissions

Whenever you use the uses-feature tag and mark it as android:requirement.required=” true”, then that application can only be installed on devices that fulfill this requirement. Which is Fingerprint sensor in this case

 <uses-feature android:name="android.hardware.fingerprint" android:required="true"/>

To access the fingerprint sensor we need to add this permission

<uses-permission android:name="android.permission.USE_FINGERPRINT" />

You complete Manifest will look like this. If You are Beginner Learn Android application development from the scratch

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mytrendin.fingerprint">

    <uses-feature android:name="android.hardware.fingerprint"
        android:required="true"/>
    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

If you really liked the article, please subscribe to our YouTube Channel for videos related to this article.Please find us on Twitter and Facebook.

Related Posts