Mobile Development 14 min read

Integrating Fingerprint Authentication on Android: APIs, Implementation Steps, and Advanced Usage

Google’s fingerprint API, introduced in Android 6.0, can be integrated via the legacy FingerprintManager or the newer BiometricPrompt, using a wrapper that abstracts version differences, handling permissions, hardware checks, authentication callbacks, and optional reflection to retrieve fingerprint IDs and enrolled fingerprint lists for advanced login scenarios.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Integrating Fingerprint Authentication on Android: APIs, Implementation Steps, and Advanced Usage

Google opened the fingerprint authentication API starting from Android 6.0. This article guides developers through the basic integration of fingerprint verification, the transition to the newer BiometricPrompt API, and advanced techniques such as obtaining fingerprint IDs and lists via reflection.

1. Basic APIs

From Android 6.0 the system provides FingerprintManager . It offers public methods to check hardware support, enrollment status, start authentication, cancel authentication, and receive callbacks. After Android 9.0 Google recommends using BiometricPrompt instead of FingerprintManager because the former cannot customize the dialog UI but is the official solution.

2. Demo Structure

The demo consists of a wrapper class FingerprintManagerWrapper that hides version differences. Two concrete implementations, FingerprintVersionM (Android 6.0‑8.0) and FingerprintVersionP (Android 9.0+), both implement the common interface IFingerprintInterface with startAuth() and canceAuth() methods.

public class FingerprintManagerWrapper {
    private IFingerprintInterface mFingerprintImp;
    public FingerprintManagerWrapper() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                mFingerprintImp = new FingerprintVersionP();
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mFingerprintImp = new FingerprintVersionM();
            }
        } catch (Exception e) { /* handle */ }
    }
    /**
     * Check if the device supports fingerprint hardware.
     */
    public boolean isHardwareDetected() {
        boolean isHardwareSupport = false;
        try {
            if (mFingerprintManager != null) {
                isHardwareSupport = mFingerprintManager.isHardwareDetected();
            }
        } catch (Exception e) { Log.e(TAG, "isHardwareDetected err", e); }
        return isHardwareSupport;
    }
    /**
     * Check whether any fingerprints have been enrolled.
     */
    public boolean hasEnrolledFingerprints() {
        boolean hasEnrolled = false;
        try {
            if (mFingerprintManager != null) {
                hasEnrolled = mFingerprintManager.hasEnrolledFingerprints();
            }
        } catch (Exception e) { Log.e(TAG, "hasEnrolledFingerprints err", e); }
        return hasEnrolled;
    }
    public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
        Log.i(TAG, "------startFingerAuthenticate() enter --------");
        if (!isHardwareDetected()) { Log.e(TAG, "------hardware not detected--------"); return; }
        if (!hasEnrolledFingerprints()) { Log.e(TAG, "-----no fingerprints enrolled--------"); return; }
        mFingerprintImp.startAuth(listener);
    }
}

3. Version‑Specific Implementations

public class FingerprintVersionM implements IFingerprintInterface {
    @Override
    public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
        CancellationSignal mCancellationSignal = new CancellationSignal();
        MyAuthenticationCallback authenticationCallback = new MyAuthenticationCallback();
        mFingerprintManager.authenticate(null, mCancellationSignal, 0, authenticationCallback, null);
    }
    @Override
    public void canceAuth() { /* cancel logic */ }
}
public class FingerprintVersionP implements IFingerprintInterface {
    @Override
    public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
        CancellationSignal mCancellationSignal = new CancellationSignal();
        BiometricPrompt.AuthenticationCallback mAuthenticationCallback = new BiometricPrompt.AuthenticationCallback() {};
        mBiometricPrompt.authenticate(mCancellationSignal, mContext.getMainExecutor(), mAuthenticationCallback);
    }
    @Override
    public void canceAuth() { /* cancel logic */ }
}

4. Callback Implementation

private class MyAuthenticationCallback extends AuthenticationCallback {
    @Override
    public void onAuthenticationFailed() { /* failure handling */ }
    @Override
    public void onAuthenticationSucceeded(AuthenticationResult result) { /* success handling */ }
    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { /* help handling */ }
    @Override
    public void onAuthenticationError(int errMsgId, CharSequence errString) { /* error handling */ }
}

5. Integration Steps (6 steps)

Add fingerprint permissions in AndroidManifest.xml : <!-- Android 9.0+ --> <uses-permission android:name="android.permission.USE_BIOMETRIC"/> <!-- Android 6.0‑8.0 --> <uses-permission android:name="android.permission.USE_FINGERPRINT"/> <!-- For obtaining fingerprint IDs (requires system permission) --> <uses-permission android:name="android.permission.MANAGE_FINGERPRINT"/>

Check at runtime whether the device supports fingerprint and whether fingerprints are enrolled (methods in the wrapper).

Call FingerprintManagerWrapper.startAuth() to launch authentication.

Implement version‑specific classes ( FingerprintVersionM and FingerprintVersionP ) as shown above.

Register the authentication callback ( MyAuthenticationCallback ) in both version implementations.

In the Activity’s onStop() method cancel the authentication: @Override protected void onStop() { super.onStop(); mCancellationSignal.cancel(); }

6. Advanced: Obtaining Fingerprint ID via Reflection

private static int getFingerId(AuthenticationResult result) {
    int fingerId = -1;
    try {
        Field field = result.getClass().getDeclaredField("mFingerprint");
        field.setAccessible(true);
        Object fingerPrint = field.get(result);
        Class
clzz = Class.forName("android.hardware.fingerprint.Fingerprint");
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            Class
supClass = clzz.getSuperclass();
            Method getBiometricId = supClass.getDeclaredMethod("getBiometricId");
            fingerId = (int) getBiometricId.invoke(fingerPrint);
        } else {
            Method getFingerId = clzz.getDeclaredMethod("getFingerId");
            fingerId = (int) getFingerId.invoke(fingerPrint);
        }
    } catch (Exception e) { Log.e(TAG, "", e); }
    return fingerId;
}

For Android 6.0 the fingerprint object contains mFingerprintId and a public getFingerprintId() method. For Android 9.0+ the ID is stored in the superclass as mBiometricId with getBiometricId() .

7. Advanced: Getting the List of Enrolled Fingerprints

public static Object getEnrolledFingerprints(FingerprintManager fm) {
    try {
        if (fm != null) {
            return invokeMethod(fm, "getEnrolledFingerprints");
        }
    } catch (Exception e) { VLog.e(TAG, "getEnrolledFingerprints()", e); }
    return null;
}

The returned object can be converted to JSON (using Gson) and mapped to a unified bean AccountFingerprint that contains fields for both Android 6.0 ( mFingerId ) and Android 9.0+ ( mBiometricId ).

8. Practical Scenario – Fingerprint Login

After obtaining the fingerprint ID and the list of fingerprints, a typical use case is to bind the device’s fingerprint data to a user account on the server. During login the client sends the fingerprint ID together with the account and device identifier; the server validates the binding and returns the authentication result.

9. Summary

The article covered:

Basic fingerprint integration using FingerprintManager and the newer BiometricPrompt .

Step‑by‑step guide to add permissions, check hardware, start/cancel authentication, and handle callbacks.

Advanced reflection techniques to retrieve hidden fingerprint IDs and the full list of enrolled fingerprints, enabling scenarios such as fingerprint‑based login.

These techniques allow developers to implement secure and user‑friendly biometric authentication across Android 6.0‑10+ devices.

JavaMobile DevelopmentAndroidauthenticationAPIFingerprintBiometric
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.