Fingerprint authentication was introduced in Android M, a new security feature that allows users to confirm their identify with a touch. Fingerprint authentication could be a very useful addition to your apps, allowing you to secure sensitive features such as in-app payments, or replace password-and-username screens with a much more convenient single-touch sign in.

In this article, I’m going to show you how to implement fingerprint authentication in your own apps.

Creating our fingerprint authentication app

Open Android Studio and create a new project.
Once you’ve created your project, we’ll need to make some adjustments to the Manifest and build the app’s user interface.
Updating the Manifest
We need access to the device’s touch sensor in order to receive fingertip touch events. Add the following line to manifest file.

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

When you mark android:required=”true,” the Google Play store will only allow users to install your app on devices that fulfil all of these hardware requirements.
If it’s marked false Google Play will permit users to download your app even if their device doesn’t have a fingerprint sensor. If you choose this approach, then your app will need to check presence of a touch sensor at runtime and then disable its fingerprint authentication features, where required.
Add permission to access the fingerprint sensor too:

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

Creating a Fingerprint helper class
All of the interesting stuff happens here. This class helps in setup the app for fingerprint authentication and notifies the activity/fragment about any message to be shown.
So what are the major functionalities of this class:

  • Set up a messaging mechanism to notify UI
  • Check software capabilities
  • Check hardware capabilities
  • Check app and device settings

If all the above steps are satisfied,

  • Create and set up a cipher to use with fingerprint authentication
  • Implement a callback which listens for events from fingerprint sensor
  • Start authentication
  • Cancel authentication

Step 1 is accomplished by adding a listener interface which needs to be implemented by activity/fragment listening for the events.

 public interface Listener { void onAuthenticationError(int errorCode, CharSequence errString); void onAuthenticationHelp(int helpCode, CharSequence helpString); void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result); void onAuthenticationFailed(); void onNoOSSupport(); void onNoSensor(); void onNoPermission(); void onNoFingerPrints(); void onLockScreen(); void onCipherError(); } 

Now lets focus on steps 2,3 and 4.

 // If app’s minSdkVersion is anything lower than 23, then you have to verify that device is running Marshmallow or higher before executing any fingerprint-related code. if (Build.VERSION.SDK_INT &amp;amp;gt;= Build.VERSION_CODES.M) { //Get an instance of KeyguardManager and FingerprintManager KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE); mFingerprintManager = (FingerprintManager) context.getSystemService(FINGERPRINT_SERVICE); //Check whether device has a fingerprint sensor if (!mFingerprintManager.isHardwareDetected()) { // If a fingerprint sensor isn’t available, then inform UI that // they will be unable to use fingerprint functionality listener.onNoSensor(); return; } //Check whether user has granted the USE_FINGERPRINT permission if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) { // If app doesn't have this permission, then notify user listener.onNoPermission(); return; } //Check user has registered at least one fingerprint if (!mFingerprintManager.hasEnrolledFingerprints()) { // If user hasn’t configured any fingerprints, then notify user listener.onNoFingerPrints(); return; } //Check that the lockscreen is secured if (!keyguardManager.isKeyguardSecure()) { // If the user hasn’t secured their lockscreen with a PIN or pattern, listener.onLockScreen(); return; } } else { listener.onNoOSSupport(); } 

Now for step 5 generate a cipher.

 private Cipher generateCipher() { try { // Obtain reference to the Standard Android Keystore KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); //Get an instance of key generator KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); //Initialize keystore keyStore.load(null); //Initialize the KeyGenerator keyGenerator.init( new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_CBC) //Configure this key so that the user has to confirm their identity with // a fingerprint each time .setUserAuthenticationRequired(true) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) .build()); //Generate the secret key SecretKey key = keyGenerator.generateKey(); //Obtain a Cipher instance and configure it with the properties required for // fingerprint authentication Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher; } catch (KeyStoreException | NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CertificateException | NoSuchPaddingException | InvalidKeyException | IOException exc) { exc.printStackTrace(); return null; } } 

Create a crypto object using the cipher instance. This crypto object will be used later for fingerprint authentication.

 Cipher cipher = generateCipher(); if (cipher != null) { //If the cipher is initialized successfully, then create a CryptoObject instance mCryptoObject = new FingerprintManager.CryptoObject(cipher); } else { listener.onCipherError(); } 

Step 6 is achieved by implementing FingerprintManager.AuthenticationCallback. This callback implementation is required to listen for events from fingerprint manager.

 mAuthCallback = new FingerprintManager.AuthenticationCallback() { @Override public void onAuthenticationError(int errorCode, CharSequence errString) { mListener.onAuthenticationError(errorCode, errString); } @Override public void onAuthenticationHelp(int helpCode, CharSequence helpString) { mListener.onAuthenticationHelp(helpCode, helpString); } @Override public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { mListener.onAuthenticationSucceeded(result); } @Override public void onAuthenticationFailed() { mListener.onAuthenticationFailed(); } }; 

Now step 7. Create a method to start authentication. This method will be called from activity/fragment when it is ready to scan the finger print.

 public void startAuth() { if (Build.VERSION.SDK_INT &amp;amp;gt;= Build.VERSION_CODES.M) { //Used later to cancel authentication. mCancellationSignal = new CancellationSignal(); mFingerprintManager.authenticate(mCryptoObject, mCancellationSignal, 0, mAuthCallback, null); } } 

For step 8, create a method to cancel authentication when appropriate.

 public void cancel() { if (mCancellationSignal != null) { mCancellationSignal.cancel(); } } 

Create UI for our sample app.

Main elements in UI would be,

  • Implement FingerPrintHandler.Listener
  • Create an instance of FingerPrintHandler
  • Add a button to start authentication process
  • Cancel authentication

First we will create a fingerprint icon. Right click on drawable folder of your project. Select New->Vector Asset. Choose finger print icon from the list.
Now we have all our resources, let’s create our UI:

 <LinearLayout xmlns:android="" xmlns:app="" xmlns:tools="" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/finger" android:layout_width="100dp" android:layout_height="100dp" android:src="@drawable/ic_fingerprint" android:layout_gravity="center_horizontal" android:layout_marginTop="50dp"/> <TextView android:id="@+id/instruction" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/instructions" android:layout_marginTop="20dp" android:layout_gravity="center_horizontal"/> </LinearLayout> 

Your user interface should look something like this:

Lets enable the buttons and listen for events. Make MainActivity implement FingerPrintHandler.Listener.
Also create an instance of FingerPrintHandler and call startAuth() when tapping on finger print ImageView we just added.

 public class MainActivity extends AppCompatActivity implements FingerPrintHandler.Listener { FingerPrintHandler mFingerPrintHandler; private TextView mInstructionsTV; private ImageView mIconView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mInstructionsTV = findViewById(; mIconView = findViewById(; mFingerPrintHandler = new FingerPrintHandler(getApplicationContext(), this); mIconView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mFingerPrintHandler.startAuth(); mInstructionsTV.setText(R.string.instructions2); } }); } @Override protected void onDestroy() { mFingerPrintHandler.cancel(); super.onDestroy(); } 

Call cancel() method in onDestroy(). This will release reference to the sensor when our app no longer requires it.

Source code for this sample app is available in github.
If you want to integrate finger print authentication to your existing project, all you need is to add the FingerPrintHelper class and implement the FingerPrintHelper.Listener

Jacks Varghese
Over 7+ Years of Experience in Design and development in embedded and Mobile application. Expertise and Executed multiple Android SDK applications for STB (Set Top Box), Google TV, and Mobile Devices.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.