卡塔尔世界杯冠军_女子乒乓球世界杯 - ecmipu.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.

*

*

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.

*

*

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)

Copyright © 2022 卡塔尔世界杯冠军_女子乒乓球世界杯 - ecmipu.com All Rights Reserved.