With Android 6, there will be official API support for fingerprint recognition. The main class used is FingerprintManager. However, this class will crash when running on android environments below 6. So have a derivative FingerprintManagerCompat and FingerprintManagerCompat23. Version 23 contains special handling of the API after version 23, and FingerprintManagerCompat determines the API internally, so we just call it directly.

static { if (Build.VERSION.SDK_INT >= 23) { IMPL = new Api23FingerprintManagerCompatImpl(); } else { IMPL = new LegacyFingerprintManagerCompatImpl(); }}Copy the code

Here I’ll show you how to get started using the official fingerprint API. One has to ask why it is called introduction. because



The first argument in this methodFingerprintManagerCompat.CryptoObject. This parameter is the key to fingerprint identification. More complex, interested in children’s shoes can be baidu usage. I didn’t cover it in the demo, but simply implemented the other basic functions of fingerprint, and wrote an auxiliary class:

public class FingerPrintHelper { static final String PREFERENCE_FINGER_PRINT_CONFIG_NAME = "fingerPrint"; static final String PREFERENCE_KEY_IS_SUPPORT_FINGER_PRINT = "isSupportFingerPrint"; static final String PREFERENCE_KEY_HAS_EVER_CHECKED = "hasEverCheckedSupportFingerPrint"; static final String TAG = "fingerPrint"; public static SharedPreferences getConfig() { return ContextUtil.getContext().getSharedPreferences(PREFERENCE_FINGER_PRINT_CONFIG_NAME, Context.MODE_PRIVATE); } public static void clearConfig() { getConfig().edit().clear().commit(); } private static void setSupportFingerPrint(boolean isSupport) { SharedPreferences.Editor editor = getConfig().edit(); editor.putBoolean(PREFERENCE_KEY_IS_SUPPORT_FINGER_PRINT, isSupport); editor.commit(); } /** * This method is only available for phones with apis lower than Android 6.0 that are supported by the handset manufacturer. Such as Xiaomi, VIVO some models. * The desirability is not very good. * * @return */ public static boolean isSupportFingerPrint() { boolean res = false; if (! hasEverCheckedFingerPrintSupport()) { res = checkSupportFingerPrint(); setSupportFingerPrint(res); setHasEverCheckedFingerPrintSupport(true); } else { res = getConfig().getBoolean(PREFERENCE_KEY_IS_SUPPORT_FINGER_PRINT, false); } return res; } private static boolean hasEverCheckedFingerPrintSupport() { return getConfig().getBoolean(PREFERENCE_KEY_HAS_EVER_CHECKED, false); } private static void setHasEverCheckedFingerPrintSupport(boolean hasEver) { SharedPreferences.Editor editor = getConfig().edit(); editor.putBoolean(PREFERENCE_KEY_HAS_EVER_CHECKED, hasEver); editor.commit(); } /** * Check that the current phone does not support fingerprint identification, Actually is to assess the current mobile API have {@ link android. Hardware. Fingerprint. FingerprintManager} this class @ return * * * / private static Boolean checkSupportFingerPrint() { boolean result = false; try { Class.forName("android.hardware.fingerprint.FingerprintManager"); Result = true; } catch (ClassNotFoundException e) { e.printStackTrace(); } return result; } /** * Start fingerprinting * @param context * @param cancellationSignal Fingerprinting cancelled controller * @param callback fingerprinting callback */ public static void doFingerPrint(Context context, android.support.v4.os.CancellationSignal cancellationSignal, FingerprintManagerCompat.AuthenticationCallback callback) { FingerprintManagerCompat managerCompat = FingerprintManagerCompat.from(context); managerCompat.authenticate(null, 0, cancellationSignal, callback, null); } /** * * * @param context * @return */ public static Boolean isHardWareDetected(context context) {return FingerprintManagerCompat.from(context).isHardwareDetected(); } /** * * * @param Context * @return */ public static Boolean hasEnrolledFingerPrint(context context) {return FingerprintManagerCompat.from(context).hasEnrolledFingerprints(); }}Copy the code

Then customize the dialog box to implement this function:

public class FingerPrintDialog extends AbstractDialogFragment implements View.OnClickListener{
    private Button btn_cancel;
    private ImageView iv_back;
    private ImageView iv_icon_finger;
    private TextView tv_title;
    private TextView tv_desc;
    private ProgressBar mProgressBar;

    private boolean enableVibrator=true;//是否开启震动
    private Vibrator mVibrator;

    private CancellationSignal mCancellationSignal;//指纹识别取消控制器

    private static final int COLOR_ERROR= R.color.colorAccent;
    private static final int COLOR_WARN=R.color.orange;
    private static final int COLOR_SUCCESS=R.color.green;

    private boolean isSuccess;//指纹识别是否成功

    private OnDismissListener mOnDismissListener;

    public void setOnDismissListener(OnDismissListener onDismissListener) {
        mOnDismissListener = onDismissListener;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mVibrator= (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE);
    }

    public static FingerPrintDialog showDialog(FragmentActivity activity, boolean cancelable, String tag, OnDismissListener onDismissListener){
        FingerPrintDialog dialog=new FingerPrintDialog();
        dialog.setCancelable(cancelable);
        dialog.setOnDismissListener(onDismissListener);
        dialog.show(activity.getSupportFragmentManager(),tag);
        dialog.startFingerPrint();
        return dialog;
    }

    public static FingerPrintDialog showDialog(FragmentActivity activity, OnDismissListener onDismissListener){
        return showDialog(activity,true,"",onDismissListener);
    }

    @Override
    protected int setLayoutId() {
        return R.layout.dialog_finger_print;
    }

    @Override
    protected void bindView(View convertView, Bundle savedInstanceState) {
        btn_cancel=findViewByIdAuto(R.id.btn_cancel);
        iv_back=findViewByIdAuto(R.id.iv_back);
        tv_title=findViewByIdAuto(R.id.tv_title);
        tv_desc=findViewByIdAuto(R.id.tv_desc);
        iv_icon_finger=findViewByIdAuto(R.id.iv_icon_finger);
        mProgressBar=findViewByIdAuto(R.id.progress);
    }

    @Override
    protected void bindEvents(View convertView, Bundle savedInstanceState) {
        Bundle data=getArguments();
        iv_back.setOnClickListener(this);
        btn_cancel.setOnClickListener(this);
        setStyle(getString(R.string.finger_print_default),STYLE_DEFAULT);
    }

    @Override
    public void onClick(View v) {
        if(v==btn_cancel){
            dismissAllowingStateLoss();
        }else if(v==iv_back){
            dismissAllowingStateLoss();
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        if(mCancellationSignal!=null){
            mCancellationSignal.cancel();
            mCancellationSignal=null;
        }
        if(mOnDismissListener!=null){
            mOnDismissListener.onDismiss(isSuccess);
        }
        super.onDismiss(dialog);
    }

    @Override
    protected int setWindowWidth() {
        return (int) (super.setWindowWidth()*0.8);
    }

    private void startFingerPrint(){
        mCancellationSignal=new CancellationSignal();
        FingerPrintHelper.doFingerPrint(ContextUtil.getContext(), mCancellationSignal,new FingerprintManagerCompat.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errMsgId, CharSequence errString) {
                super.onAuthenticationError(errMsgId, errString);
                setStyle(errString.toString(),STYLE_ERROR);
                startVibrate();
            }

            @Override
            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                super.onAuthenticationHelp(helpMsgId, helpString);
                setStyle(helpString.toString(),STYLE_WARN);
                startVibrate();
            }

            @Override
            public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                setStyle(getString(R.string.finger_print_success),STYLE_SUCCESS);
                startVibrate();
                isSuccess=true;
                (new Handler()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        dismissAllowingStateLoss();
                    }
                },1000);
            }

            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                setStyle(getString(R.string.finger_print_failed),STYLE_ERROR);
                startVibrate();
            }
        });
    }

    public void startVibrate(){
        if(enableVibrator && mVibrator!=null){
            mVibrator.vibrate(200);
        }
    }

    private static final int STYLE_DEFAULT=0;
    private static final int STYLE_SUCCESS=1;
    private static final int STYLE_ERROR=-1;
    private static final int STYLE_WARN=2;

    private void setStyle(String msg, int style){
        tv_desc.setText(msg);
        mProgressBar.setVisibility(View.VISIBLE);
        switch (style){
            case STYLE_ERROR:
                tv_desc.setTextColor(ColorKit.getColorSrc(COLOR_ERROR));
                DrawableKit.setDrawableTintColor(iv_icon_finger.getDrawable(),COLOR_ERROR);
                break;
            case STYLE_WARN:
                tv_desc.setTextColor(ColorKit.getColorSrc(COLOR_WARN));
                DrawableKit.removeDrawableTintColor(iv_icon_finger.getDrawable());
                break;
            case STYLE_SUCCESS:
                tv_desc.setTextColor(ColorKit.getColorSrc(COLOR_SUCCESS));
                DrawableKit.setDrawableTintColor(iv_icon_finger.getDrawable(),COLOR_SUCCESS);
                mProgressBar.setVisibility(View.GONE);
                break;
            default:
                tv_desc.setTextColor(ColorKit.getColorSrc(R.color.white_gray));
                DrawableKit.removeDrawableTintColor(iv_icon_finger.getDrawable());
                break;

        }
    }

    /**
     * 描述:对话框消失的时候的监听器
     *
     * <br>作者: cjs
     * <br>创建时间: 2017/11/8 0008 15:26
     * <br>邮箱: [email protected]
     * @version 1.0
     */
    public interface OnDismissListener{
        /**
         * 对话框消失的时候
         * @param isSuccess 验证是否成功
         */
        void onDismiss(boolean isSuccess);
    }
}Copy the code

Usage here:

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(FingerPrintHelper.isHardWareDetected(this) && FingerPrintHelper.hasEnrolledFingerPrint(this)){ FingerPrintDialog.showDialog(this, false, "fingerPrint", new FingerPrintDialog.OnDismissListener() { @Override public void onDismiss(boolean isSuccess) { if(isSuccess){ setContentView(R.layout.activity_main); }else{ finish(); System.exit(0); }}}); }else{toast.maketext (this," The current phone does not support android native fingerprint system or you have not set fingerprint password ", toast.length_long).show(); setContentView(R.layout.activity_main); }}}Copy the code

PS: So far, I have passed the test with Samsung S8 Plus. For other models, interested children’s shoes can download and test themselves.

  • SimpleNews News client (10920 views, 366 downloads)
  • DragGridView drag-and-sort (5973 views, 72 downloads)
  • Bihu force (8624 views, 117 downloads)
  • Welfare GankMM(3494 views, 26 downloads)
  • Yhb-2.0 (3160 views, 32 downloads)