指纹适配记录

Posted by Kosmos on December 18, 2018

注意:系统默认的每段时间验证指纹次数为5次 次数用完之后自动关闭验证,并且30秒之内不允行在使用验证

指纹验证根据Api分两个阶段

  • 第一阶段:api小于Build.VERSION_CODES.M(Android 6.0=23),系统不支持指纹系统。(部分定制(红米)手机暂不考虑)
  • 第二阶段:api小于Build.VERSION_CODES.P(Android 9.0=28),谷狗封装了support,上面那个过时了

零.权限

权限(不用动态申请): ```xml


## 一.第一阶段

> Api小于23,做法:弹个吐司说,你手机太撇。
>
> 23<= Api <28,的做法是通过指纹管理类:`FingerprintManager`

[工具类源码](https://github.com/KosmoSakura/KosmosUtils/blob/master/app/src/main/java/cos/mos/utils/tool/UFinger.java)

#### 1.0.获取实例[指纹管理器]

```java
private FingerprintManager fingerMgr;

private UFinger() {
    fingerMgr = (FingerprintManager)KApp.getInstance().
        getSystemService(Context.FINGERPRINT_SERVICE);
}

1.1.是否有指纹硬件

public boolean hasFingerHard() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return false;
    }
    if (fingerMgr == null) {
        return false;
    }
    return fingerMgr.isHardwareDetected();
}

1.2.是否有录入指纹

public boolean hasFingerInput() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return false;
    }
    if (fingerMgr == null) {
        return false;
    }
    return fingerMgr.hasEnrolledFingerprints();
}

1.3.指纹识别

@RequiresApi(api = Build.VERSION_CODES.M)
public void authenticate() {
    fingerMgr.authenticate(null, new CancellationSignal(), 0, new FingerprintManager.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode, CharSequence errString) {
            //多次指纹验证错误后,回调此方法;
            //并且,(第一次错误)由系统锁定30s
            if (listener != null) {
                listener.onResult(false, "多次错误,暂时锁定");
            }
        }

        @Override
        public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
            //指纹验证成功
            //result这里的result是指纹数据,需要相应的key才能拿出来用
            if (listener != null) {
                listener.onResult(false, "验证成功");
            }
        }

        @Override
        public void onAuthenticationFailed() {
            //指纹验证失败
            if (listener != null) {
                listener.onResult(false, "指纹不匹配");
            }
        }
    },null);
}

二、第二阶段

Android P,指纹管理器FingerprintManager被谷狗的 生物识别BiometricPrompt替换。(现在面部、虹膜等现在还只有一个占位)

虽然是提出的方法是基于Android P,但是谷狗封装的Android support或者AndroidX中已经对低版本做了兼容,所以可以直接使用FingerprintManagerCompat

工具类源码

2.0.获取实例[指纹管理器]

private final FingerprintManagerCompat compat;
private UBiometric() {
    compat = FingerprintManagerCompat.from(KApp.getInstance());
}

2.1.是否有指纹硬件

public boolean hasFingerHard() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return false;
    }
    if (compat == null) {
        return false;
    }
    return compat.isHardwareDetected();
}

2.2.是否有录入指纹

public boolean hasFingerInput() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return false;
    }
    if (compat == null) {
        return false;
    }
    return compat.hasEnrolledFingerprints();
}

2.3.指纹识别

public void authenticate(FingerListener listener) {
    //必须重新实例化。cancel过,资源会被释放,
    cancelSignal = new CancellationSignal();
    compat.authenticate(null,//用于通过指纹验证取出AndroidKeyStore中key的值
                        0,//系统建议为0,其他值,谷狗占位用于其他生物验证
                        cancelSignal,//强制取消指纹验证
                        new FingerprintManagerCompat.AuthenticationCallback() {
                            @Override
                            public void onAuthenticationError(int errMsgId, CharSequence errString) {
                                super.onAuthenticationError(errMsgId, errString);
                                //多次指纹验证错误后,回调此方法;
                                //并且,(第一次错误)由系统锁定30s
                                //多次指纹验证错误后,回调此方法;
                                //并且,(第一次错误)由系统锁定30s
                                if (listener != null) {
                                    listener.onResult(false, "多次错误,暂时锁定");
                                }
                            }

                            @Override
                            public void onAuthenticationFailed() {
                                if (listener != null) {
                                    listener.onResult(false, "指纹不匹配");
                                }
                            }

                            @Override
                            public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                                super.onAuthenticationSucceeded(result);
                                //指纹验证成功
                                //result这里的result是指纹数据,需要相应的key才能拿出来用
                                if (listener != null) {
                                    listener.onResult(true, "验证成功");
                                }
                            }
                        }, null);// 内部验证消息通过Handler传递,不需要,传空
}

一般,还会有判断系统是否设置过锁屏这个操作,不过我觉得没有必要,因为,现在录入指纹,自动就锁屏了