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方法启动验证。

  1. 创建一个BiometricPrompt
 mBiometricPrompt = BiometricPrompt(`activity or fragment`, `BiometricPrompt.AuthenticationCallback`)
  1. 进行验证
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.fingerprintdemoimport android.content.Context
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivityclass BiometricUtils {private val mBuilder: BiometricPrompt.PromptInfo.Builder = BiometricPrompt.PromptInfo.Builder()private var mBiometricPrompt: BiometricPrompt? = nullprivate var mAuthenticationErrorListener: IAuthenticationErrorListener? = nullprivate var mAuthenticationSucceededListener: IAuthenticationSucceededListener? = nullprivate 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 = listenerreturn this}fun setAuthenticationSucceededListener(listener: IAuthenticationSucceededListener): BiometricUtils {mAuthenticationSucceededListener = listenerreturn this}fun setAuthenticationFailedListener(listener: IAuthenticationFailedListener): BiometricUtils {mAuthenticationFailedListener = listenerreturn 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 指纹验证相关推荐

  1. Android 指纹相关调研

    Android 指纹相关调研 背景:公司产品同学提出要接入指纹,用于登录场景,提高转化率,由于之前没接触过指纹,接下来就是指纹的相关调查. 一:指纹的优势 我们传统的登录方式,需要用户输入用户名和密码 ...

  2. Android指纹识别,提升APP用户体验,从这里开始

    本文由 左海龙 授权投稿 原文链接:https://blog.csdn.net/hailong0529/article/details/95406183 写在前面 指纹识别大家都不陌生,现在比较新的安 ...

  3. android7.0 谷歌拼音,谷歌浏览器在Android 7.0及以上版本支持使用指纹验证进行无密码登录...

    原标题:谷歌浏览器在Android 7.0及以上版本支持使用指纹验证进行无密码登录 来源:蓝点网 此前谷歌已经宣布与 FIDO 联盟达成合作关系并在安卓系统上调用指纹或面部识别等来登录某些支持的网站. ...

  4. android 指纹识别支付 secure os,Android指纹登录/指纹支付简述

    一.简述 业务需求,需要指纹登录,鉴于市面上的资料不是特别齐全,走了不少弯路.现在通了,写点东西给大伙做个参考.末尾会提供demo和参考资料 二.指纹登录/支付工作流程 指纹验证加密流程.png 最新 ...

  5. android指纹fingerprint学习总结

    文章目录 android指纹的软件框图 android指纹的软件框图 录入指纹enroll和验证指纹verify的流程: 当手指按到指纹模组上后,指纹模组产生一个中断,在指纹的linux driver ...

  6. android指纹java_Android

    Android M指纹的资料太少,经过一段时间阅读原生Android代码,写了以下例子,贡献出来给需要帮助的人. 以下内容基于64位的高通CPU,搭载fpc1020芯片,此部分代码在原生android ...

  7. Android指纹识别

    Android指纹识别 原文:Android指纹识别 上一篇讲了通过FingerprintManager验证手机是否支持指纹识别,以及是否录入了指纹,这里进行指纹的验证. //获取Fingerprin ...

  8. Android 指纹识别(Touch ID)实例

    指纹识别   指纹识别的支持是Android6.0以后才开始的,Google也为指纹识别提供了一些列接口,指纹识别将要用到的核心API为FingerprintManager,其中还有三个核心内部类:F ...

  9. Android指纹支付 - android M / P 全适配

    前言 先说一下为什么会发布出这个库吧.很多没做过指纹相关功能肯定和我一开始一样认为:指纹支付很简单官方封装好的Api调用一下就好了,熟悉几个Api的事情.但是呢,这只是识别指纹,真正的指纹识别应用设计 ...

  10. 支付宝指纹服务器暂时用不了,解决支付宝指纹验证失效的问题

    为了提升产品的竞争力,很多手机厂商都会不定期对经典型号提供固件升级服务.但是,很多手机在经历大版本的系统更新后总会出现一些Bug.以华为荣耀8为例,在更新EMUI5.0后,就容易出现支付宝指纹验证失效 ...

最新文章

  1. varchar和Nvarchar区别 ----转载
  2. 修改citrix 默认侦听端口的命令和XML Service端口
  3. 2019王小的Java学习之路
  4. python enumerate_Python中enumerate用法详解
  5. LINUX 第七章 Squid配置
  6. 小学五年级计算机听课记录表,小学五年级语文教师听课记录
  7. ad中pcb双面板怎么设置_html中表格tr的td单元格怎么设置宽度属性
  8. sklearn交叉验证2-【老鱼学sklearn】
  9. SQL数据库学习总结(一)
  10. 什么是Power Apps?
  11. 以往WiFi的最大痛点,终于被WiFi 7给解决掉了
  12. linux log4cxx 静态库,log4cxx的个人实践
  13. Dan Pitt卸任ONF执行董事
  14. 华尔街见闻-2016年2月
  15. SDUT 2504 多项式求和
  16. 进程创建-终止-等待-替换
  17. 面向对象的特征之一:抽象
  18. vscode指定中英文字体设置
  19. Android百度地图使用
  20. 在Centos 6.4系统下安装配置fetion飞信机器人

热门文章

  1. 新浪云 node.js项目的部署
  2. ppt流程图箭头分叉_箭头循环图ppt模板_PPT结构图制作中箭头跟着目标走的技巧_ppt箭头流程图模板_ppt箭头循环图...
  3. 学习游戏服务器编程提高篇
  4. 带头节点 (非头指针) 双向链表 (doubly linked list)
  5. 基于react hook的砸金蛋动画
  6. 学习笔记-Matlab二维绘图
  7. JMS之——ActiveMQ 高可用与负载均衡集群安装、配置(ZooKeeper + LevelDB + Static discovery)
  8. STM32-DMA控制器
  9. rtk手簿Android代码,中海达rtk手机测量软件(Hi-Survey Road)
  10. java jui_求教java大神,下面这个JUI界面是怎么布局而成的