android6.0之后谷歌对指纹识别进行了官方支持,FingerprintManagerCompat 是其中实现指纹识别的一种方式。
1.添加权限
2.获取一个FingerPrintManagerCompat的实例
FingerprintManagerCompat manager = FingerprintManagerCompat.from(this);
3.判断条件
是否录入指纹,有些设备上即使录入了指纹,但是没有开启锁屏密码的话此方法还是返回 false
注:目前位置google任然没有开放让普通app启动指纹注册界面的权限
@RequiresPermission("android.permission.USE_FINGERPRINT")
public boolean hasEnrolledFingerprints() {
if (VERSION.SDK_INT < 23) {
return false;
} else {
FingerprintManager fp = getFingerprintManagerOrNull(this.mContext);
return fp != null && fp.hasEnrolledFingerprints();
}
}
判断是否硬件支持
@RequiresPermission("android.permission.USE_FINGERPRINT")
public boolean isHardwareDetected() {
if (VERSION.SDK_INT < 23) {
return false;
} else {
FingerprintManager fp = getFingerprintManagerOrNull(this.mContext);
return fp != null && fp.isHardwareDetected();
}
}
判断是否开启锁屏密码
KeyguardManager mKeyManager = (KeyguardManager) mActivity.getSystemService(Context.KEYGUARD_SERVICE);
private boolean isKeyguardSecure() {
try {
return mKeyManager.isKeyguardSecure();
} catch (Exception e) {
return false;
}
4.启动指纹识别
@RequiresPermission("android.permission.USE_FINGERPRINT")
public void authenticate(@Nullable FingerprintManagerCompat.CryptoObject crypto,
int flags,
@Nullable CancellationSignal cancel,
@NonNull FingerprintManagerCompat.AuthenticationCallback callback,
@Nullable Handler handler) {
if (VERSION.SDK_INT >= 23) {
FingerprintManager fp = getFingerprintManagerOrNull(this.mContext);
if (fp != null) {
// ...
}
}
}
这个方法是FingerprintManagerCompat类的公有方法,把这个方法需要的几个参数给他,最后在调用他,这个功能大体就实现了。
开始验证后,什么时候停止由系统来确定,如果验证成功,那么系统会关系sensor,如果失败,则允许
多次尝试,如果依旧失败,则会拒绝一段时间,然后关闭sensor,过一段时候之后再重新允许尝试
参数1,FingerprintManagerCompat.CryptoObject crypto
crypto这是一个加密类的对象,指纹扫描器会使用这个对象来判断认证结果的合法性。
这个对象可以是null,但是这样的话,就意味着app无条件信任认证的结果,
这个过程可能被攻击,数据可以被篡改,这是app在这种情况下必须承担的风险。
因此,建议这个参数不要置为null。这个类的实例化有点麻烦,主要使用javax的security接口实现。
参数2,int flags
一般传0
参数3,CancellationSignal cancel
这个对象用来在指纹识别器扫描用户指纹的是时候取消当前的扫描操作
如果已经取消的情况下,还会调用到指纹验证,就需要重新创建
if (cancellationSignal == null) {
cancellationSignal = new CancellationSignal();
}
if (cancellationSignal.isCanceled()) {
cancellationSignal = new CancellationSignal();
}
参数4,FingerprintManagerCompat.AuthenticationCallback callback
重点,需要传入一个FingerprintManagerCompat.AuthenticationCallback的子类
并重写一些方法,不同的情况回调不同的函数
参数5,Handler handler
一般传null
5.FingerprintManagerCompat.AuthenticationCallback 回调内容
private FingerprintManagerCompat.AuthenticationCallback authenticationCallback
= new FingerprintManagerCompat.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
super.onAuthenticationError(errMsgId, errString);
LogUtils.i("onAuthenticationError:" + errMsgId + ":" + errString);
// 当出现错误的时候回调此函数,比如多次尝试都失败了的时候,errString是错误信息
}
@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
super.onAuthenticationHelp(helpMsgId, helpString);
LogUtils.i("onAuthenticationHelp:" + helpMsgId + ":" + helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
LogUtils.i("onAuthenticationSucceeded");
// 当验证的指纹成功时会回调此函数,然后不再监听指纹sensor
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
LogUtils.i("onAuthenticationFailed");
// 当指纹验证失败的时候会回调此函数,失败之后允许多次尝试,
失败次数过多会停止响应一段时间然后再停止sensor的工作
}
};
回调1、onAuthenticateError(int errMsgId, CharSequence errString)
每次重新授权,哪怕不去校验,取消时会走,其中errMsgId==5
回调2、onAuthenticationFailed
当指纹识别失败后,会调用onAuthenticationFailed()方法,这时候指纹传感器并没有关闭,
谷歌原生系统给了我们5次重试机会,也就是说,连续调用了4次onAuthenticationFailed()方法后,
第5次会调用onAuthenticateError(int errMsgId, CharSequence errString)方法,此时errMsgId==7。
回调3、onAuthenticationError()和onAuthenticationSucceeded()
当系统调用了后,传感器会关闭,只有我们重新授权,再次调用authenticate()方法后才能继续使用指纹识别功能。
回调4、onAuthenticationHelp
OnAuthenticationHelp方法是出现了可以回复的异常才会调用的。什么是可以恢复的异常呢?
一个常见的例子就是:手指移动太快,当我们把手指放到传感器上的时候,如果我们很快地将手指移走的话,
那么指纹传感器可能只采集了部分的信息,因此认证会失败。
但是这个错误是可以恢复的,因此只要提示用户再次按下指纹,并且不要太快移走就可以解决。
回调5、OnAuthenticationSucceeded
这个接口会在认证成功之后回调。我们可以在这个方法中提示用户认证成功。
这里需要说明一下,如果我们上面在调用authenticate的时候,我们的CryptoObject不是null的话,
那么我们在这个方法中可以通过AuthenticationResult来获得Cypher对象然后调用它的doFinal方法。
doFinal方法会检查结果是不是会拦截或者篡改过,如果是的话会抛出一个异常。
当我们发现这些异常的时候都应该将认证当做是失败来来处理,为了安全建议大家都这么做。
6.取消指纹扫描
当cancellationSignal不是空,并且不是取消态,就需要取消扫描
cancellationSignal.cancel();
ingerprintManagerCompat
一个用以访问指纹硬件的类
FingerprintManagerCompat.AuthenticationCallback
提供给方法authenticate的回调结构对象
FingerprintManagerCompat.AuthenticationResult
一个用来存放来自方法authenticate的回调数据的容器。
FingerprintManagerCompat.CryptoObject
FingerprintManager所支持的加密对象的包装类。
1.兼容android6.0以下系统的话,不要使用FingerprintManagerCompat, 低于M的系统版本,FingerprintManagerCompat无论手机是否有指纹识别模块,均认为没有指纹识别,可以用FingerprintManager来做。
参考:https://www.jb51.net/article/111399.htm
https://blog.csdn.net/qqoopp332211/article/details/53364863