Android 指纹验证
Posted Android-kongqw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 指纹验证相关的知识,希望对你有一定的参考价值。
android 指纹验证
本篇记录一下在Android上做指纹校验的过程。在某些敏感场景,可以通过指纹验证操作者是否是设备主人。
本篇使用的androidx
下的Biometric
来实现的,FingerprintManagerCompat
已经被官方标记过时,就不过多描述了。
加入依赖
implementation 'androidx.biometric:biometric:1.1.0'
检查是否支持指纹验证
检查设备硬件是否支持或者是否设置了指纹(至少一个或更多)
BiometricManager.BIOMETRIC_SUCCESS == BiometricManager.from(context).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
进行验证
核心类BiometricPrompt
,通过authenticate
方法启动验证。
- 创建一个
BiometricPrompt
mBiometricPrompt = BiometricPrompt(`activity or fragment`, `BiometricPrompt.AuthenticationCallback`)
- 进行验证
mBiometricPrompt?.authenticate(`BiometricPrompt.PromptInfo`)
上面伪代码中BiometricPrompt
的第一个参数,为Activity或Fragment,第二个参数为识别验证的回调,代码如下:
/**
* A collection of methods that may be invoked by @link BiometricPrompt during authentication.
*/
public abstract static class AuthenticationCallback
/**
* Called when an unrecoverable error has been encountered and authentication has stopped.
*
* <p>After this method is called, no further events will be sent for the current
* authentication session.
*
* @param errorCode An integer ID associated with the error.
* @param errString A human-readable string that describes the error.
*/
public void onAuthenticationError(@AuthenticationError int errorCode, @NonNull CharSequence errString)
/**
* Called when a biometric (e.g. fingerprint, face, etc.) is recognized, indicating that the
* user has successfully authenticated.
*
* <p>After this method is called, no further events will be sent for the current
* authentication session.
*
* @param result An object containing authentication-related data.
*/
public void onAuthenticationSucceeded(@NonNull AuthenticationResult result)
/**
* Called when a biometric (e.g. fingerprint, face, etc.) is presented but not recognized as
* belonging to the user.
*/
public void onAuthenticationFailed()
- onAuthenticationError:指纹识别异常回调,包含几个常用错误码,详见:
- onAuthenticationSucceeded:指纹识别通过回调
- onAuthenticationFailed:指纹识别不通过回调
onAuthenticationError 错误码
/**
* An error code that may be returned during authentication.
*/
@IntDef(
ERROR_HW_UNAVAILABLE,
ERROR_UNABLE_TO_PROCESS,
ERROR_TIMEOUT,
ERROR_NO_SPACE,
ERROR_CANCELED,
ERROR_LOCKOUT,
ERROR_VENDOR,
ERROR_LOCKOUT_PERMANENT,
ERROR_USER_CANCELED,
ERROR_NO_BIOMETRICS,
ERROR_HW_NOT_PRESENT,
ERROR_NEGATIVE_BUTTON,
ERROR_NO_DEVICE_CREDENTIAL
)
@Retention(RetentionPolicy.SOURCE)
@interface AuthenticationError
上面伪代码中authenticate
方法的参数,为设置验证指纹弹窗的基础参数,代码大概长这样:
val promptInfo: BiometricPrompt.PromptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("这里设置Title")
.setSubtitle("这里设置Subtitle")
.setDescription("这里设置Description")
// .setDeviceCredentialAllowed(false)
.setNegativeButtonText("这里设置关闭按钮文案")
// .setAllowedAuthenticators()
.setConfirmationRequired(true)
.build()
流程很简单,下面提供一个工具类,可以直接拿去用:
BiometricUtils.kt
package com.kongqw.fingerprintdemo
import android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
class BiometricUtils
private val mBuilder: BiometricPrompt.PromptInfo.Builder = BiometricPrompt.PromptInfo.Builder()
private var mBiometricPrompt: BiometricPrompt? = null
private var mAuthenticationErrorListener: IAuthenticationErrorListener? = null
private var mAuthenticationSucceededListener: IAuthenticationSucceededListener? = null
private var mAuthenticationFailedListener: IAuthenticationFailedListener? = null
/**
* 是否支持指纹识别
*/
fun isSupportBiometric(context: Context): Boolean
return try
BiometricManager.BIOMETRIC_SUCCESS == BiometricManager.from(context).canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK)
catch (e: Exception)
e.printStackTrace()
false
fun setTitle(title: String): BiometricUtils
mBuilder.setTitle(title)
return this
fun setSubtitle(subtitle: String): BiometricUtils
mBuilder.setSubtitle(subtitle)
return this
fun setDescription(description: String): BiometricUtils
mBuilder.setDescription(description)
return this
fun setNegativeButtonText(negativeButtonText: String): BiometricUtils
mBuilder.setNegativeButtonText(negativeButtonText)
return this
fun setAuthenticationErrorListener(listener: IAuthenticationErrorListener): BiometricUtils
mAuthenticationErrorListener = listener
return this
fun setAuthenticationSucceededListener(listener: IAuthenticationSucceededListener): BiometricUtils
mAuthenticationSucceededListener = listener
return this
fun setAuthenticationFailedListener(listener: IAuthenticationFailedListener): BiometricUtils
mAuthenticationFailedListener = listener
return this
fun authenticate(fragmentActivity: FragmentActivity, succeededListener: IAuthenticationSucceededListener? = null, errorListener: IAuthenticationErrorListener? = null)
succeededListener?.apply mAuthenticationSucceededListener = succeededListener
errorListener?.apply mAuthenticationErrorListener = errorListener
mBiometricPrompt = BiometricPrompt(fragmentActivity, /* command -> command?.run() ,*/ FingerCallBack())
mBiometricPrompt?.authenticate(mBuilder.build())
fun authenticate(fragment: Fragment, succeededListener: IAuthenticationSucceededListener? = null, errorListener: IAuthenticationErrorListener? = null)
succeededListener?.apply mAuthenticationSucceededListener = succeededListener
errorListener?.apply mAuthenticationErrorListener = errorListener
mBiometricPrompt = BiometricPrompt(fragment, /* command -> command?.run() ,*/ FingerCallBack())
mBiometricPrompt?.authenticate(mBuilder.build())
inner class FingerCallBack : BiometricPrompt.AuthenticationCallback()
override fun onAuthenticationError(errorCode: Int, errString: CharSequence)
super.onAuthenticationError(errorCode, errString)
mAuthenticationErrorListener?.onAuthenticationError(errorCode, errString)
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult)
super.onAuthenticationSucceeded(result)
mBiometricPrompt?.cancelAuthentication()
mAuthenticationSucceededListener?.onAuthenticationSucceeded(result)
override fun onAuthenticationFailed()
super.onAuthenticationFailed()
mAuthenticationFailedListener?.onAuthenticationFailed()
interface IAuthenticationErrorListener
fun onAuthenticationError(errorCode: Int, errString: CharSequence)
interface IAuthenticationSucceededListener
fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult)
interface IAuthenticationFailedListener
fun onAuthenticationFailed()
使用
初始化
private val mBiometricUtils = BiometricUtils()
检查是否支持指纹验证
val isSupportBiometric = mBiometricUtils.isSupportBiometric(applicationContext)
开始验证
mBiometricUtils.setTitle("指纹验证")
.setSubtitle("需要身份验证")
.setDescription("Description")
.setNegativeButtonText("关闭吧")
.setAuthenticationSucceededListener(object : BiometricUtils.IAuthenticationSucceededListener
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult)
Toast.makeText(applicationContext, "指纹通过", Toast.LENGTH_SHORT).show()
)
.setAuthenticationFailedListener(object : BiometricUtils.IAuthenticationFailedListener
override fun onAuthenticationFailed()
Toast.makeText(applicationContext, "指纹不通过", Toast.LENGTH_SHORT).show()
)
.setAuthenticationErrorListener(object : BiometricUtils.IAuthenticationErrorListener
override fun onAuthenticationError(errorCode: Int, errString: CharSequence)
// when(errorCode)
// BiometricPrompt.ERROR_HW_UNAVAILABLE -> ""
// BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> ""
// BiometricPrompt.ERROR_TIMEOUT -> ""
// BiometricPrompt.ERROR_NO_SPACE -> ""
// BiometricPrompt.ERROR_CANCELED -> ""
// BiometricPrompt.ERROR_LOCKOUT -> ""
// BiometricPrompt.ERROR_VENDOR -> ""
// BiometricPrompt.ERROR_LOCKOUT_PERMANENT -> ""
// BiometricPrompt.ERROR_USER_CANCELED -> ""
// BiometricPrompt.ERROR_NO_BIOMETRICS -> "未注册任何指纹"
// BiometricPrompt.ERROR_HW_NOT_PRESENT -> ""
// BiometricPrompt.ERROR_NEGATIVE_BUTTON -> ""
// BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> ""
//
Toast.makeText(applicationContext, "onAuthenticationError($errorCode, $errString)", Toast.LENGTH_SHORT).show()
)
mBiometricUtils.authenticate(this)
以上是关于Android 指纹验证的主要内容,如果未能解决你的问题,请参考以下文章