Android App Add Fingerprint Lock

Posted by smeagal on Tue, 06 Aug 2019 09:18:07 +0200

Preface

At the time of Android 6.0 (Api23), the Android system added the fingerprint recognition api interface, Fingerprint Manager, which defined the most basic fingerprint recognition interface. However, at the time of AndroidP (Api28), the official no longer recommended it and did @Deprecated processing.

Later, the Fingerprint Manager Compat class was added to the support v4 library. In fact, the Fingerprint Manager was encapsulated to some extent. In essence, Fingerprint Manager was used to realize fingerprint recognition.

Recently, I also met this need in the project. I need to add an application lock like Alipay every time I open APP. Let me introduce my usage below.

1. Version Judgment

if (Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT < 28)

Use the old Fingerprint Manager at api23, and Fingerprint Manager Compat after api28, because I had some problems in judging the version of Fingerprint Manager Compat in the process of using it.

2. Create instances

FingerprintManagerCompat mFingerprintManagerCompat = FingerprintManagerCompat.from(context);
CancellationSignal mCancellationSignal = new CancellationSignal();

Fingerprint Manager Compat is an example we're going to use, and Cancellation Signal is used to turn off fingerprint verification

3. Open Verification

  mFingerprintManagerCompat.authenticate(null, 0, mCancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() {
                @Override
                public void onAuthenticationError(int errorCode, CharSequence errString) {
                    super.onAuthenticationError(errorCode, errString);
                    if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
                        fpResult.error(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, errString);
                }

                @Override
                public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                    super.onAuthenticationHelp(helpCode, helpString);

                }

                @Override
                public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                    super.onAuthenticationSucceeded(result);

                    fpResult.success();
                }

                @Override
                public void onAuthenticationFailed() {
                    super.onAuthenticationFailed();

                    fpResult.retry(0, "authentication failed");
                }
            }, null);

authenticate() is the key method. The figure above is the required parameters. We will introduce them one by one.

CryptoObject: It is an encrypted object. Fingerprint scanner will use this object to judge the validity of the scanning results. Normally, null can be transmitted. Interested friends can go to the official website for detailed explanation.
flags: Temporarily 0. No other information is available.
Cancellation Signal: This is what we described above to cancel the current scan operation.
Authentication Callback: Callback, which is the most critical, has four methods
OnAuthentication Error: Failure will be executed many times. If the Android side fails five times, it will have 30 seconds of non-operability. You can give a hint here to judge that code is equal to 7.
OnAuthentication Succeeded: Success
OnAuthentication Failed: Authentication Failed
OnAuthentication Help: Some errors call back this method and can be handled as appropriate
Handler: No need to deal with it. You can execute the operation in the callback above.

ok, I'll post my tool class for your reference.

import android.app.KeyguardManager;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
import android.support.v4.os.CancellationSignal;
import android.util.Log;
import android.widget.Toast;

import cn.com.goldwind.eis.R;

public class FingerPrintUtils {

    private FingerprintManagerCompat mFingerprintManagerCompat;
    private CancellationSignal mCancellationSignal;
    private Context context;

    public FingerPrintUtils(Context context) {
        this.context = context;
        if (mFingerprintManagerCompat == null || mCancellationSignal == null) {
            mFingerprintManagerCompat = FingerprintManagerCompat.from(context);
            mCancellationSignal = new CancellationSignal();
        }
    }

    public interface FingerPrintResult {
        void success();

        void error(int code, CharSequence info);

        void retry(int code, CharSequence info);
    }

    /**
     * Close
     *
     * @return
     */
    public boolean cancelCallback() {
        if (mCancellationSignal != null && !mCancellationSignal.isCanceled()) {
            mCancellationSignal.cancel();
            mCancellationSignal = null;
            return true;
        } else {
            return false;
        }
    }

    /**
     * start
     */
    public void start(final FingerPrintResult fpResult) {
        if (fpResult == null) {
            throw new RuntimeException("FingerPrintUtils.init()parameter Context perhaps FingerPrintResult by null");
        }
        if (mFingerprintManagerCompat.isHardwareDetected() && mFingerprintManagerCompat.hasEnrolledFingerprints()) {
            mFingerprintManagerCompat.authenticate(null, 0, mCancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() {
                @Override
                public void onAuthenticationError(int errorCode, CharSequence errString) {
                    Log.d("-=-", "onAuthenticationError" + errString);
                    super.onAuthenticationError(errorCode, errString);
                    if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
                        fpResult.error(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, errString);
                    }// else {
//                        fpResult.retry(errorCode, errString);
//                    }
                }

                @Override
                public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
                    super.onAuthenticationHelp(helpCode, helpString);
                    Log.d("-=-", "onAuthenticationHelp" + helpString);
//                    fpResult.retry(helpCode, helpString);
                }

                @Override
                public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                    super.onAuthenticationSucceeded(result);
                    Log.d("-=-", "onAuthenticationSucceeded" + result);
                    fpResult.success();
                }

                @Override
                public void onAuthenticationFailed() {
                    super.onAuthenticationFailed();
                    Log.d("-=-", "onAuthenticationFailed");
                    fpResult.retry(0, "authentication failed");
                }
            }, null);
        } else {
            fpResult.error(-1, context.getString(R.string.fingerprint_recognition_not_support));
        }
    }

    /**
     * Determine whether fingerprint recognition is supported
     */
    public boolean supportFingerprint() {
        if (Build.VERSION.SDK_INT < 23) {
            Toast.makeText(context, context.getString(R.string.fingerprint_recognition_not_support), Toast.LENGTH_SHORT).show();
            return false;
        } else {
            KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
            FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(context);
            if (!fingerprintManager.isHardwareDetected()) {
                Toast.makeText(context, context.getString(R.string.fingerprint_recognition_not_support), Toast.LENGTH_SHORT).show();
                return false;
            } else if (keyguardManager != null && !keyguardManager.isKeyguardSecure()) {
                Toast.makeText(context, context.getString(R.string.fingerprint_recognition_not_support), Toast.LENGTH_SHORT).show();
                return false;
            } else if (!fingerprintManager.hasEnrolledFingerprints()) {
                Toast.makeText(context, context.getString(R.string.fingerprint_recognition_not_enrolled), Toast.LENGTH_SHORT).show();
                return false;
            }
        }
        return true;
    }
}

What I have given above is Fingerprint Manager Compat, which can write a Fingerprint Manager by itself. The api is basically the same, and the invocation method is the same.

 

 

Topics: Android