How to Add Fingerprint Authentication in Android using android studio

0 974

Fingerprint Authentication in Android

Fingerprint Authentication in AndroidAndroid is the most popular mobile operating system in date. Especially Android 6.0 provides some interesting new features for its users and developers. Let me explain you about them:

  • Fingerprint Authentication
  • Confirm Credential
  • App Linking
  • Auto Backup for Apps
  • Direct Share
  • Voice Interactions
  • Assist API
  • Adoptable Storage Device
  • And Much more

Today we will discuss one of the features named: ‘Fingerprint Authentication’. Android 6.0 provides new APIs to help you authenticate users through fingerprint scans on devices that support this feature. I will explain you to implement Fingerprint Authentication in your Application. For authenticating users through fingerprint sensor, create an instance of the newly implemented FingerprintManager class by calling authenticate() method. You should run your App on the suitable device that has a fingerprint sensor. And you have to implement the user interface on your app for the fingerprint authentication. In your UI you have to use the standard Android fingerprint icon. Every App must authenticate the user’s fingerprint individually if multiple Apps use the fingerprint authentication.

Is Using Fingerprint Authentication a Good Idea ? and Benefits of using Fingerprint Authentication

  • Your fingerprints will never alter or lost, whatever the conditions are your identity will never change.
  • Its usage is fast, consistent and dependable.
  • You can make sure that it’s you who has unlocked is through unique fingerprints.
  • Online transactions have become more suitable because of fingerprint authentication.

so let’s start building the app

  • Create a new Project.
  • Select File and choose New Project to create a new project in Android Studio and change the version of SDK to Android 6.0 (API123).
  • Next step: Now you have to add USE_FINGERPRINT permission to AndroidManifest.xml file because you are working with fingerprint authentication.
<uses-permission android:name="android.permission.USE_FINGERPRINT" />

Next step go to MainActivity.java and write below codes. This class contains the following methods and functions like OnCreate() method that includes activity_main.xmlgenerateKey() function produces an encryption key that can be stored safely on the device.cipherInit() function to initialize the cipher to create the encrypted FingerprintManager. CryptoObject instance checks before starting the authentication process.

package com.example.boss.fingerprintauthentication;

import android.Manifest;
import android.annotation.TargetApi;
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.TextView;

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 javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

public class MainActivity extends AppCompatActivity {


    private KeyStore keyStore;
    // Variable used for storing the key in the Android Keystore container
    private static final String KEY_NAME = "Ebound";
    private Cipher cipher;
    private TextView textView;


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


        // Initializing both Android Keyguard Manager and Fingerprint Manager
        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);


        textView = (TextView) findViewById(R.id.errorText);


        // Check whether the device has a Fingerprint sensor.
        if(!fingerprintManager.isHardwareDetected()){
            /**
             * An error message will be displayed if the device does not contain the fingerprint hardware.
             * However if you plan to implement a default authentication method,
             * you can redirect the user to a default authentication activity from here.
             * Example:
             * Intent intent = new Intent(this, DefaultAuthenticationActivity.class);
             * startActivity(intent);
             */
            textView.setText("not found Fingerprint Sensor in your device");
        }else {
            // Checks whether fingerprint permission is set on manifest
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
                textView.setText("permission for Fingerprint authentication not enabled");
            }else{
                // Check whether at least one fingerprint is registered
                if (!fingerprintManager.hasEnrolledFingerprints()) {
                    textView.setText("Register fingerprint in Settings one time");
                }else{
                    // Checks whether lock screen security is enabled or not
                    if (!keyguardManager.isKeyguardSecure()) {
                        textView.setText("Please enable Lock screen security in Settings");
                    }else{
                        generateKey();


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


    @TargetApi(Build.VERSION_CODES.M)
    protected void generateKey() {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
        } catch (Exception e) {
            e.printStackTrace();
        }


        KeyGenerator keyGenerator;
        try {
            keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new RuntimeException("Failed to get KeyGenerator instance", e);
        }


        try {
            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 (NoSuchAlgorithmException |
                InvalidAlgorithmParameterException
                | IOException e) {
            throw new RuntimeException(e);
        } catch (java.security.cert.CertificateException e) {
            e.printStackTrace();
        }
    }


    @TargetApi(Build.VERSION_CODES.M)
    public boolean cipherInit() {
        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 | UnrecoverableKeyException | IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        } catch (java.security.cert.CertificateException e) {
            e.printStackTrace();
        }
        return false;
    }
}

Write the code given below to create a layout xml file named  to activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_fingerprint"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    tools:context="com.example.boss.fingerprintauthentication.MainActivity">

    <LinearLayout
        android:id="@+id/headerLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:gravity="center"
        android:orientation="vertical">


        <ImageView
            android:id="@+id/icon"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginBottom="30dp"
            android:paddingTop="2dp"
            android:src="@drawable/fingerprint" />


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="20dp"
            android:text="@string/title_fingerprint"
            android:textColor="@color/textPrimary"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:gravity="center"
            android:paddingEnd="30dp"
            android:paddingStart="30dp"
            android:text="@string/desc_fingerprint"
            android:textAlignment="center"
            android:textColor="@color/textPrimary"
            android:textSize="16sp" />


        <TextView
            android:id="@+id/errorText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:gravity="center"
            android:paddingEnd="30dp"
            android:paddingStart="30dp"
            android:textAlignment="center"
            android:textColor="@color/errorText"
            android:textSize="14sp" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="26dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:text="@string/note"
        android:textAlignment="center"
        android:textColor="@color/textPrimaryDark"
        android:textSize="14sp" />

</RelativeLayout>

SecondActivity.java

Right-click on your Project, NewActivityBasic Activity to create an Activity and update the following files as shown below.

package com.example.boss.fingerprintauthentication;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

}
  • Add these code to activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/content_home"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.boss.fingerprintauthentication.SecondActivity"
    tools:showIn="@layout/activity_second">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="@string/activity_home_desc"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        android:textSize="24sp" />


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="24dp"
        android:text="@string/activity_home_note"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        android:textSize="14sp" />

</RelativeLayout>
  •  Creating Fingerprint Authentication Handler Class.
  •  Create the Hander class by naming it FingerprintHandler.java, that extends FingerprintManager.AuthenticationCallback and contains some extra modules. Replace the code given below with the one in FingerprintHandler.java file.
package com.example.boss.fingerprintauthentication;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.TextView;

/**
 * Created by Boss on 12/8/2016.
 */

public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {


    private Context context;


    // Constructor
    public FingerprintHandler(Context mContext) {
        context = mContext;
    }


    public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {
        CancellationSignal 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) {
        this.update("Fingerprint Authentication errorn" + errString, false);
    }


    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
        this.update("Fingerprint Authentication helpn" + helpString, false);
    }


    @Override
    public void onAuthenticationFailed() {
        this.update("Fingerprint Authentication failed.", false);
    }


    @Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        this.update("Fingerprint Authentication succeeded.", true);
    }


    public void update(String e, Boolean success) {
        TextView textView = (TextView) ((Activity) context).findViewById(R.id.errorText);
        textView.setText(e);
        if (success) {
            textView.setTextColor(ContextCompat.getColor(context, R.color.colorPrimaryDark));
        }
    }
}
  • To update the file open colors.xml file which you could find under resvalues
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="textPrimary">#1a1717</color>
    <color name="textPrimaryDark">#1182b7</color>
    <color name="errorText">#d10d0d</color>
</resources>
  • Then update the file by opening strings.xml file found in resvalues.
<resources>
    <string name="app_name">Fingerprint Authentication</string>
    <string name="title_activity_main">MainActivity</string>
    <string name="title_fingerprint">One-touch Sign In</string>
    <string name="desc_fingerprint">identify yourself by placing finger on the scanner</string>
    <string name="note">one fingerprint should be registered in device settings</string>
    <string name="title_activity_home">Fingerprint</string>
    <string name="activity_home_desc">You have successfully logged in</string>
    <string name="activity_home_note">re-open the app to see the fingerprint auth screen again by closing this app</string>
</resources>

⦁Using Android Image Assets you can create the fingerprint icon. For this, right click the drawable folder then create a NewImage Asset named it the fingerprint.

Read also: How to add Push notification in Android using Firebase (cloud messaging)

Testing the Project

  • Testing on a physical device
  • Your project is almost complete now you have to debug the App on a physical Android device by putting your fingertip on the fingerprint scanner. The user will get to the Home Activity as
  • shown below if Fingerprint authentication is successful.
  • Android Fingerprint Authentication.
  • Testing on an Emulator

To test an App on an emulator follows the following steps:

  • If you have not installed Android SDK Tools Revision 24.3 then install it.
  • in emulator Go to SettingsSecurityFingerprint and follow the enrollment instructions to Enroll a new fingerprint in the emulator.
  • To emulate the fingerprint touch events use an emulator with the following command given below. This command can be used in fingerprint touch events on the lock screen or in the App.

adb -e emu finger touch <finger_id>

I hope you learned how to add Fingerprint Authentication in Android.

Comments

comments

Leave A Reply

Your email address will not be published.