Android从6.0系统开始就支持指纹认证功能了,指纹功能还需要有硬件支持才行

指纹与手机系统设置的指纹进行匹配

如图:

在LoginActivity 中弹出指纹验证Fragment,验证成功进入MainActivity中

代码:

创建FingerprintDialogFragment 继承 DialogFragment

package com.chuanye.zhiwendemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast; import javax.crypto.Cipher; public class FingerprintDialogFragment extends DialogFragment { private FingerprintManager fingerprintManager; private CancellationSignal mCancellationSignal; private Cipher mCipher; private LoginActivity mActivity; private TextView errorMsg; /**
* 标识是否是用户主动取消的认证。
*/
private boolean isSelfCancelled; public void setCipher(Cipher cipher) {
mCipher = cipher;
} @Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (LoginActivity) getActivity();
} @SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fingerprintManager = getContext().getSystemService(FingerprintManager.class);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);
} @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fingerprint_dialog, container, false);
errorMsg = v.findViewById(R.id.error_msg);
TextView cancel = v.findViewById(R.id.cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
stopListening();
}
});
return v;
} @Override
public void onResume() {
super.onResume();
// 开始指纹认证监听
startListening(mCipher);
} @Override
public void onPause() {
super.onPause();
// 停止指纹认证监听
stopListening();
} @SuppressLint({"MissingPermission", "NewApi"})
private void startListening(Cipher cipher) {
isSelfCancelled = false;
mCancellationSignal = new CancellationSignal();
fingerprintManager.authenticate(new FingerprintManager.CryptoObject(cipher), mCancellationSignal, 0, new FingerprintManager.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
if (!isSelfCancelled) {
errorMsg.setText(errString);
if (errorCode == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
Toast.makeText(mActivity, errString, Toast.LENGTH_SHORT).show();
dismiss();
}
}
} @Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
errorMsg.setText(helpString);
} @Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
Toast.makeText(mActivity, "指纹认证成功", Toast.LENGTH_SHORT).show();
mActivity.onAuthenticated();
} @Override
public void onAuthenticationFailed() {
errorMsg.setText("指纹认证失败,请再试一次");
}
}, null);
} @SuppressLint("NewApi")
private void stopListening() {
if (mCancellationSignal != null) {
mCancellationSignal.cancel();
mCancellationSignal = null;
isSelfCancelled = true;
}
} }

  布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_fp_40px"
/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:text="请验证指纹解锁"
android:textColor="#000"
android:textSize="16sp"
/> <TextView
android:id="@+id/error_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:maxLines="1"
android:textSize="12sp"
android:textColor="#f45"
/> <View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginTop="10dp"
android:background="#ccc"
/> <TextView
android:id="@+id/cancel"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:text="取消"
android:textColor="#5d7883"
android:textSize="16sp"
/> </LinearLayout>

  LoginActivity 中

package com.chuanye.zhiwendemo;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.KeyguardManager;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast; import java.security.KeyStore; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey; public class LoginActivity extends AppCompatActivity {
//https://blog.csdn.net/guolin_blog/article/details/81450114 private static final String DEFAULT_KEY_NAME = "default_key"; KeyStore keyStore; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login); if (supportFingerprint()) {//判断是否支持指纹
initKey();
initCipher();
}
} /**
* 判断是否支持指纹
* @return
*/
@SuppressLint("MissingPermission")
public boolean supportFingerprint() {
if (Build.VERSION.SDK_INT < 23) {
Toast.makeText(this, "您的系统版本过低,不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
} else {
//键盘锁管理者
KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
//指纹管理者
FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
if (!fingerprintManager.isHardwareDetected()) {//判断硬件支不支持指纹
Toast.makeText(this, "您的手机不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
} else if (!keyguardManager.isKeyguardSecure()) {//还未设置锁屏
Toast.makeText(this, "您还未设置锁屏,请先设置锁屏并添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
} else if (!fingerprintManager.hasEnrolledFingerprints()) {//指纹未登记
Toast.makeText(this, "您至少需要在系统设置中添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
}
}
return true;
} @TargetApi(23)
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);
}
} @TargetApi(23)
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);
showFingerPrintDialog(cipher);
} catch (Exception e) {
throw new RuntimeException(e);
}
} private void showFingerPrintDialog(Cipher cipher) {
FingerprintDialogFragment fragment = new FingerprintDialogFragment();
fragment.setCipher(cipher);
fragment.show(getSupportFragmentManager(), "fingerprint");
} public void onAuthenticated() {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
} }

  activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已进入App主界面"
android:textSize="18sp"
android:layout_gravity="center"
/> </FrameLayout>

  最后添加权限

<uses-permission android:name="android.permission.USE_FINGERPRINT"></uses-permission>

  注意,通常为了让用户清楚的知道现在需要进行指纹认证,Google官方建议最好使用一个通用的指纹图标,而不应该由各APP制作自己的指纹图标。为此,Google也特意提供了一套指纹认证的组图,可以 点击这里 查看和下载。

指纹认证不能单独使用,必须要配合着图案或其他认证方式一起来使用,因为一定要提供一个在设备不支持指纹情况下的其他认证方式

另外FingerprintManager在最新的Android 9.0系统上已经被废弃了因为Android 9.0系统提供了更加强大的生物识别认证功能,包括指纹识别、面部识别、甚至是虹膜识别等等,因此仅仅只能用于指纹识别的FingerprintManager已经不能满足新系统的强大需求了。

参考与郭神的https://blog.csdn.net/guolin_blog/article/details/81450114

Android 中指纹识别的更多相关文章

  1. Android中的指纹识别

    转载请注明出处:http://blog.csdn.net/wl9739/article/details/52444671 评论中非常多朋友反映,依据我给出的方案,拿不到指纹信息这个问题,在这里统一说明 ...

  2. Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)

    指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...

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

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

  4. Android指纹识别API讲解,让你有更好的用户体验

    我发现了一个比较怪的现象.在iPhone上使用十分普遍的指纹认证功能,在Android手机上却鲜有APP使用,我简单观察了一下,发现Android手机上基本上只有支付宝.微信和极少APP支持指纹认证功 ...

  5. Android指纹识别深入浅出分析到实战

    指纹识别这个名词听起来并不陌生,但是实际开发过程中用得并不多.Google从Android6.0(api23)开始才提供标准指纹识别支持,并对外提供指纹识别相关的接口.本文除了能适配6.0及以上系统, ...

  6. android指纹识别、拼图游戏、仿MIUI长截屏、bilibili最美创意等源码

    Android精选源码 一个动画效果的播放控件,播放,暂停,停止之间的动画 用 RxJava 实现 Android 指纹识别代码 Android仿滴滴打车(滴滴UI)源码 Android高仿哔哩哔哩动 ...

  7. 检查Android是否支持指纹识别以及是否已经录入指纹

    原文:检查Android是否支持指纹识别以及是否已经录入指纹 Android M 开始,系统中加入了指纹相关功能. 主要用到的类为:FingerprintManager 只提供三个方法: 返回值 方法 ...

  8. Android指纹识别

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

  9. WAF指纹识别和XSS过滤器绕过技巧

    [译文] -- “Modern Web Application Firewalls Fingerprinting and Bypassing XSS Filters” 0x1 前言 之前在乌云drop ...

随机推荐

  1. C# 运行时的关系

    简介 记录c#对象在托管堆中运行时的相互关系,如下记录了一个方法在执行时候的生命周期,当方法在之前,CLR会先执行将方法里面所有用到的局部变量.参数对应的内存地址等全部存放当前线程栈当中,并且会将所有 ...

  2. [b0034] python 归纳 (十九)_线程同步_条件变量

    代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...

  3. TypeScript 学习笔记(一)

    TypeScript: 1.是 JavaScript 的一个超集,支持 ES6 标准 2.由微软开发的自由和开源的编程语言 3.设计目标是开发大型应用,它可编译成纯 JavaScript,编译出来的 ...

  4. 告诉你一些DBA求职面试技巧

    告诉你一些DBA求职面试技巧 要自信!永远不要低估你的能力.如果你不了解什么问题的答案,承认它.重点放在你找出答案的能力和你学习的意愿. 不要自大!是的,你可能过于自信而被认为是骄傲的.轻率的,甚至是 ...

  5. vue全局路由守卫beforeEach+token验证+node

    在后端安装jsonwebtoken         npm i jsonwebtoken --save 在 login.js文件中引入      // 引入jwtconst jwt = require ...

  6. C++学习七 C++实现add(1)(2)(3)

    一.代码实现: class Yoba { public: Yoba(int n) : _n(n) {} Yoba operator() (int n) { return Yoba(_n + n); } ...

  7. linux学习(六)文件基本属性

    Linux系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限.为了保护系统的安全性,Linux系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定. 在Linux中我们可 ...

  8. jQuery的配置。

    在python中有提前定义模板的功能,所以提前将jQuery的导入语句导入就可以直接使用jQuery语法: 一.下载jQuery包. 下载官网: https://jquery.com/ 可下载迷你版的 ...

  9. 鲜贝7.3--pycharm切换

    在pycharm中切换python版本 打开软件会看到,这里有明显的红色提示错误.原因是当前使用的是python3.3,当执行print的时候,打印的文字需要小括号’()‘括起来. 在工具栏中找到这个 ...

  10. Python IO 模式

    IO 模式 对于 Linux 的 network IO: 一次 IO 访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区 copy 到应用程序的地址空间.所 ...