思路

开始条件

  1. 判断系统版本是否在6.0之后
  2. 判断手机是否支持指纹
  3. 判断手机中是否已经录入相关指纹(锁屏)
  4. 以上条件全部满足后,可以进行指纹验证

指纹验证的情况分为3中:

  1. 验证通过(success),之后进行用户登录、跳转界面等操作
  2. 验证失败(failed),次数内的失败,例如一次失败后的提示(倒计次数)、震动等操作
  3. 验证失败(failed),达到五次后,提示次数过多,跳转到密码登录(要么30秒后指纹登录,要么提示这一次只能密码登录)

注:

  • 8.0之前,指纹只能错误5次,达到5次时会禁止指纹认证,同时开启30秒倒计时,等待结束后重置错误计数,继续认证
  • 8.0之后,依然是每错误5次就会倒计时30秒,然而30秒结束后错误计数并不会被清空,
  • 8.0上加入了最大20次的限制,累计错误20次之后就无法使用指纹认证功能了,只能用密码的方式才能重置错误计数
  • 9.0之后它。。。。。。被抛弃了 -.-||
  • ic_fp_40px.png
  • 本文参考了郭霖大神的文章

根据官方demo修改代码如下:

FingerprintDialogFragment 代码:

@TargetApi(23)
public class FingerprintDialogFragment extends DialogFragment {private RelativeLayout fingerprintContainer;private TextView fingerprintDescription, fingerprintStatus;private ImageView fingerprintIcon;private RelativeLayout backupContainer;private FrameLayout description;private TextView passwordDescription, newFingerprintEnrolledDescription;private EditText password;private CheckBox useFingerprintInFutureCheck;private LinearLayout buttonPanel;private Button cancelButton, secondDialogButton;private FingerprintManager fingerprintManager;private CancellationSignal mCancellationSignal;private Cipher mCipher;private static final String DEFAULT_KEY_NAME = "default_key";private KeyStore keyStore;private Stage mStage = Stage.FINGERPRINT;private int flag = 5;           // 验证次数private int countdown = 1;      // 时间倒计时private boolean isSelfCancelled;// 标识是否是用户主动取消的认证// 是否支持指纹public boolean supportFingerprint() {if (Build.VERSION.SDK_INT < 23) {Toast.makeText(getContext(), "您的系统版本过低,不支持指纹功能", Toast.LENGTH_SHORT).show();return false;} else {KeyguardManager keyguardManager = getContext().getSystemService(KeyguardManager.class);FingerprintManager fingerprintManager = getContext().getSystemService(FingerprintManager.class);if (fingerprintManager != null) {if (!fingerprintManager.isHardwareDetected()) {Toast.makeText(getContext(), "您的手机不支持指纹功能", Toast.LENGTH_SHORT).show();return false;} else if (keyguardManager != null) {if (!keyguardManager.isKeyguardSecure()) {Toast.makeText(getContext(), "您还未设置锁屏,请先设置锁屏并添加一个指纹", Toast.LENGTH_SHORT).show();return false;} else if (!fingerprintManager.hasEnrolledFingerprints()) {Toast.makeText(getContext(), "您至少需要在系统设置中添加一个指纹", Toast.LENGTH_SHORT).show();return false;}} else {Toast.makeText(getContext(), "键盘管理初始化失败", Toast.LENGTH_SHORT).show();return false;}} else {Toast.makeText(getContext(), "指纹管理初始化失败", Toast.LENGTH_SHORT).show();return false;}}return true;}// 初始化密钥库private void initKey() {try {keyStore = KeyStore.getInstance("AndroidKeyStore");keyStore.load(null);KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,KeyProperties.PURPOSE_ENCRYPT |KeyProperties.PURPOSE_DECRYPT).setBlockModes(KeyProperties.BLOCK_MODE_CBC).setUserAuthenticationRequired(true).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);keyGenerator.init(builder.build());keyGenerator.generateKey();} catch (Exception e) {throw new RuntimeException(e);}}// 初始化密钥private void initCipher() {try {SecretKey key = (SecretKey) keyStore.getKey(DEFAULT_KEY_NAME, null);Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"+ KeyProperties.BLOCK_MODE_CBC + "/"+ KeyProperties.ENCRYPTION_PADDING_PKCS7);cipher.init(Cipher.ENCRYPT_MODE, key);setCipher(cipher);} catch (Exception e) {throw new RuntimeException(e);}}public void setCipher(Cipher cipher) {mCipher = cipher;}// 向Activity传值的接口public interface FragmentInteraction {void onEditPassword(String strPassword);//输入的密码void onAuthenticated();//验证成功}private FragmentInteraction listener;private void initView(View view) {// 指纹登录fingerprintContainer = (RelativeLayout) view.findViewById(R.id.fingerprint_container);fingerprintDescription = (TextView) view.findViewById(R.id.fingerprint_description);fingerprintIcon = (ImageView) view.findViewById(R.id.fingerprint_icon);fingerprintStatus = (TextView) view.findViewById(R.id.fingerprint_status);// 密码登录backupContainer = (RelativeLayout) view.findViewById(R.id.backup_container);description = (FrameLayout) view.findViewById(R.id.description);passwordDescription = (TextView) view.findViewById(R.id.password_description);newFingerprintEnrolledDescription = (TextView) view.findViewById(R.id.new_fingerprint_enrolled_description);password = (EditText) view.findViewById(R.id.password);useFingerprintInFutureCheck = (CheckBox) view.findViewById(R.id.use_fingerprint_in_future_check);// 下方按钮buttonPanel = (LinearLayout) view.findViewById(R.id.buttonPanel);cancelButton = (Button) view.findViewById(R.id.cancel_button);secondDialogButton = (Button) view.findViewById(R.id.second_dialog_button);getDialog().setCancelable(false);getDialog().setCanceledOnTouchOutside(false);}private void initEvent() {cancelButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (mStage == Stage.FINGERPRINT) {stopListening();dismiss();} else if (mStage == Stage.PASSWORD) {password.setText("");dismiss();}}});secondDialogButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (mStage == Stage.FINGERPRINT) {goToPassword();} else if (mStage == Stage.PASSWORD) {//LogUtil( "输入密码是:" + password.getText().toString());listener.onEditPassword(password.getText().toString());dismiss();}}});}@Overridepublic void onAttach(Context context) {super.onAttach(context);listener = (FragmentInteraction) context;}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);if (supportFingerprint()) {fingerprintManager = getContext().getSystemService(FingerprintManager.class);initKey();initCipher();} else {LogUtil("关闭dialog");dismiss();}}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {getDialog().setTitle("指纹验证");View v = inflater.inflate(R.layout.dialog_fingerprint, container, false);initView(v);initEvent();LogUtil("Fragment名字:" + getTag());return v;}@Overridepublic void onResume() {super.onResume();// 开始指纹认证监听startListening(mCipher);}@Overridepublic void onPause() {super.onPause();// 停止指纹认证监听stopListening();}@Overridepublic void onDetach() {super.onDetach();listener = null;//把传递进来的activity对象释放掉}private void startListening(Cipher cipher) {isSelfCancelled = false;mCancellationSignal = new CancellationSignal();fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {@Overridepublic void onAuthenticationError(int errorCode, CharSequence errString) {if (!isSelfCancelled) {fingerprintStatus.setText(errString);if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {//多次指纹密码验证错误后,进入此方法;并且,不能短时间内调用指纹验证Message message = new Message();message.what = -1;message.obj = errString;myHandler.sendMessage(message);}}}@Overridepublic void onAuthenticationHelp(int helpCode, CharSequence helpString) {fingerprintStatus.setText(helpString);}@Overridepublic void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {Message message = new Message();message.what = 1;myHandler.sendMessage(message);}@Overridepublic void onAuthenticationFailed() {Message message = new Message();message.what = 0;myHandler.sendMessage(message);}}, null);}private void stopListening() {if (mCancellationSignal != null) {mCancellationSignal.cancel();mCancellationSignal = null;isSelfCancelled = true;}}@SuppressLint("HandlerLeak")private Handler myHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case -1:LogUtil("handleMessage---多次失败");/*if (flag == 0) {// 传值失败时的系统时间,用来判断是否可以再次开启指纹DateFormat dateFormat = DateFormat.getDateInstance(R.string.data_format);listener.process(dateFormat.format(new Date(System.currentTimeMillis())));}*/Toast.makeText(getContext(), msg.obj.toString(), Toast.LENGTH_SHORT).show();goToPassword();//dismiss();break;case 1:LogUtil("handleMessage---成功");fingerprintIcon.setImageResource(R.drawable.ic_fingerprint_success);fingerprintStatus.setText("成功");fingerprintStatus.setTextColor(fingerprintStatus.getResources().getColor(R.color.success_color));fingerprintStatus.postDelayed(mSucceedFingerRunnable, countdown * 1000);break;case 0:flag--;LogUtil("指纹识别失败,还剩下" + flag + "次机会");fingerprintIcon.setImageResource(R.drawable.ic_fingerprint_error);fingerprintStatus.setText("指纹识别失败,还剩下" + flag + "次机会");fingerprintStatus.setTextColor(fingerprintStatus.getResources().getColor(R.color.red));fingerprintStatus.postDelayed(mResetFingerRunnable, countdown * 1000);break;default:break;}}};private Runnable mResetFingerRunnable = new Runnable() {@Overridepublic void run() {fingerprintStatus.setText("重新验证");fingerprintStatus.setTextColor(fingerprintStatus.getResources().getColor(R.color.grey));fingerprintIcon.setImageResource(R.mipmap.ic_fp_40px);}};private Runnable mSucceedFingerRunnable = new Runnable() {@Overridepublic void run() {listener.onAuthenticated();dismiss();}};private void goToPassword() {cancelButton.setText(R.string.s_btn_cancel);secondDialogButton.setText(R.string.s_btn_ok);fingerprintContainer.setVisibility(View.GONE);backupContainer.setVisibility(View.VISIBLE);mStage = Stage.PASSWORD;password.requestFocus();stopListening();}private void LogUtil(String msg) {Log.e("指纹界面:", msg);}public enum Stage {FINGERPRINT,NEW_FINGERPRINT_ENROLLED,PASSWORD}
}

dialog_fingerprint布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><FrameLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><includelayout="@layout/fingerprint_dialog_content" /><includelayout="@layout/fingerprint_dialog_backup"android:visibility="gone"/></FrameLayout><LinearLayoutandroid:id="@+id/buttonPanel"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingStart="12dp"android:paddingEnd="12dp"android:paddingTop="4dp"android:paddingBottom="4dp"android:gravity="bottom"><Spaceandroid:id="@+id/spacer"android:layout_width="0dp"android:layout_height="0dp"android:layout_weight="1"android:visibility="invisible" /><Buttonandroid:id="@+id/cancel_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="取消"/><Buttonandroid:id="@+id/second_dialog_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="密码登陆"/></LinearLayout></LinearLayout>

fingerprint_dialog_backup布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/backup_container"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingTop="16dp"android:paddingBottom="8dp"><FrameLayoutandroid:id="@+id/description"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_alignParentStart="true"android:layout_marginStart="24dp"android:layout_marginEnd="24dp"android:layout_alignParentLeft="true"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="输入你的密码"android:id="@+id/password_description"android:textSize="18sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="A new fingerprint was added to this device, so your password is required."android:id="@+id/new_fingerprint_enrolled_description"android:visibility="gone"android:textColor="?android:attr/textColorSecondary" /></FrameLayout><EditTextandroid:id="@+id/password"android:layout_width="wrap_content"android:layout_height="wrap_content"android:inputType="textPassword"android:ems="10"android:hint="密码"android:imeOptions="actionGo"android:layout_below="@+id/description"android:layout_marginTop="16dp"android:layout_marginStart="20dp"android:layout_marginEnd="20dp"android:layout_alignParentStart="true"android:layout_alignParentLeft="true" /><CheckBoxandroid:id="@+id/use_fingerprint_in_future_check"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/password"android:layout_alignParentStart="true"android:layout_marginTop="16dp"android:layout_marginStart="20dp"android:layout_marginEnd="20dp"android:checked="true"android:visibility="gone"android:text="Use fingerprint in the future"android:layout_alignParentLeft="true" /></RelativeLayout>

fingerprint_dialog_content布局代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/fingerprint_container"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="8dp"android:paddingStart="24dp"android:paddingEnd="24dp"android:paddingTop="16dp"><TextViewandroid:id="@+id/fingerprint_description"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:textSize="18sp"android:text="请确认指纹" /><ImageViewandroid:id="@+id/fingerprint_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/fingerprint_description"android:layout_marginTop="20dp"android:src="@mipmap/ic_fp_40px"/><TextViewandroid:id="@+id/fingerprint_status"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBottom="@+id/fingerprint_icon"android:layout_alignTop="@+id/fingerprint_icon"android:gravity="center_vertical"android:text="请进行指纹验证"android:textColor="@color/darkgray"android:layout_marginLeft="16dp"android:layout_toRightOf="@+id/fingerprint_icon" /></RelativeLayout>

指纹使用(FingerprintManager)相关推荐

  1. android的指纹问题

    检查逻辑 //是否支持指纹 if (!fingerprintManager.isHardwareDetected()) {return; }//权限 if (ActivityCompat.checkS ...

  2. Android开发学习—指纹识别系统的原理与使用

    指纹识别是什么? 提到指纹识别我们就要先弄清楚什么事指纹,指纹为何能够做到区别性. 指纹,由于其具有终身不变性.唯一性和方便性,已几乎成为生物特征识别的代名词.指纹是指人的手指末端正面皮肤上凸凹不平产 ...

  3. 如何实现Android指纹登录

    一.概述 指纹识别通过指纹传感器采集信息,进行指纹图像的预处理,然后进行特征点提取,最后进行特征匹配.一般指纹识别的用途有:系统解锁.应用锁.支付认证.普通的登录认证. 指纹识别两种场景 本地识别:在 ...

  4. Android使用指纹识别功能

    指纹识别是在Android 6.0以后新增的功能,在使用的时候需要先判断手机的系统版本是否支持指纹识别. AndroidManifest添加权限 <uses-permission android ...

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

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

  6. android xml 指纹动画,如何检查设备是否具有指纹功能并在Android中使用

    API 28的最新版本 AndroidManifest.xml文件 现在,您可以使用: val executor = activity.mainExecutor val cancelListener ...

  7. Android开发学习之路-指纹识别api

    在android6.0之后谷歌对指纹识别进行了官方支持,今天还在放假,所以就随意尝试了一下这个api,但是遇到了各种各样的问题 ①在使用FingerPrintManager这个类实现的时候发现了很多问 ...

  8. android指纹java_Android

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

  9. android keyguard,Android8.1 SystemUI Keyguard之指纹解锁流程

    手指在指纹传感器上摸一下就能解锁,Keyguard是怎么做到的呢? 下面我们就跟着源码,解析这整个过程. 何时开始监听指纹传感器? 先来看下IKeyguardService这个binder接口有哪些回 ...

最新文章

  1. 动机模型_一个模型教你如何激发学习动机
  2. RDO Packstack 安装 Openstack Icehouse CentOS 6.5 单网卡
  3. 【转载】SharpDevelop代码分析
  4. Your WebGL implementation doesn't seem to support hardware accelerated rendering. Check your browser
  5. ie内核浏览器_[正式版下载] 微软全新 Chrome 内核 Edge 浏览器!原生支持 Chrome 插件扩展...
  6. uml图中的各种箭头_一次搞懂建模语言UML
  7. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
  8. BZOJ 1113: [Poi2008]海报PLA
  9. 综合日语第一册第十四课
  10. linux shell脚本关于文件存在与否的判断
  11. STM8单片机低功耗---活跃停机(Active Halt)模式实现-1
  12. 买手机需要128 G的存储空间吗?
  13. 【CometOJ】CometOJ#8 解题报告
  14. 同济大学高等数学上册电子版_同济大学版高等数学 第七版 上册 课本
  15. 网狐cocos2d-lua棋牌二次开发搭建教程
  16. 像素越多越好?像元的面积越小越好?为何底大一级压死人?
  17. 如何在html上显示时间设置,如何在网页上显示日期的两种方法
  18. Node 插件 爬取王者荣耀官网英雄信息,并生成数据库
  19. leetcode刷题记录--数据结构;深度优先搜索算法;二叉树;平衡树;1020. 飞地的数量;1669. 合并两个链表;108. 将有序数组转换为二叉搜索树
  20. ✨字符串de介绍及其常见的api

热门文章

  1. 【TCP】【JPerf】基于STM32H7开发板的TCP性能测试
  2. nfdump分析netflow
  3. 计算机培训总结ppt用什么音乐,音乐教育行业年终总结ppt
  4. AD-NeRF 由音频和人脸图像合成人脸视频并表现出自然的说话风格
  5. ibm tivoli_IBM Tivoli Directory Server 6.0的SSL配置
  6. 1、vivado新建工程
  7. 车联网解决方案,“人,车,平台“三位一体
  8. ANSYS学习1--概述
  9. 华为模拟器eNSP的安装
  10. win10 Easy Sysprep 5.19封装失败