android指纹解锁

In this tutorial, we’ll be discussing the Android Fingerprint API and implement a Fingerprint Dialog in our android application.

在本教程中,我们将讨论Android Fingerprint API,并在android应用程序中实现Fingerprint Dialog。

Android指纹管理器 (Android Fingerprint Manager)

Fingerprint Manager is the class used to access the Fingerprint hardware from the device (if it exists).

指纹管理器是用于从设备(如果存在)访问指纹硬件的类。

Google recommends authenticating fingerprint in applications by displaying a DialogFragment with a Fingerprint icon to the user.

Google建议通过向用户显示带有指纹图标的DialogFragment来对应用程序中的指纹进行身份验证。

In order to implement Fingerprint Authentication, you need to add the following permission in the AndroidManifest.xml file:

为了实现指纹认证,您需要在AndroidManifest.xml文件中添加以下权限 :

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

Following are the steps to implement Fingerprint Authentication in your application:

以下是在您的应用程序中实现指纹认证的步骤:

  • Check whether there is a secure lock on the lock screen检查锁屏上是否有安全锁
  • Check whether the Fingerprint Hardware is available using the FingerprintManager class.使用FingerprintManager类检查指纹硬件是否可用。
  • Check whether the user has enrolled at least one fingerprint.检查用户是否注册了至少一个指纹。
  • Get access to Android keystore to store a key used to initiate a Cipher.获取对Android密钥库的访问权限,以存储用于启动密码的密钥。
  • Start the Authentication Method and add the callback methods启动身份验证方法并添加回调方法

The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device.

Android Keystore系统可让您将加密密钥存储在容器中,以使其更难从设备中提取。

项目结构 (Project Structure)

码 (Code)

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="START AUTHENTICATION"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>

The code for the dialog_fingerprint.xml is given below:

下面给出了dialog_fingerprint.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="24dp"android:paddingTop="24dp"android:paddingRight="24dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"><TextViewandroid:id="@+id/titleTextView"android:layout_width="0dp"android:layout_height="wrap_content"android:text="Fingerprint Dialog"android:textAppearance="?android:attr/textAppearanceLarge"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent" /><TextViewandroid:id="@+id/subtitleTextView"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="Confirm fingerprint to continue."app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/titleTextView" /><android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="28dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/subtitleTextView"app:srcCompat="@drawable/ic_fingerprint_white_24dp" /><TextViewandroid:id="@+id/errorTextView"android:layout_width="0dp"android:layout_height="0dp"android:layout_marginStart="16dp"android:gravity="center_vertical"android:text="Touch sensor"app:layout_constraintBottom_toBottomOf="@id/fab"app:layout_constraintLeft_toRightOf="@id/fab"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@id/fab" /><LinearLayoutandroid:id="@+id/buttons"style="?android:attr/buttonBarStyle"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:gravity="end"android:orientation="horizontal"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/fab"><Buttonandroid:id="@+id/btnCancel"style="?android:attr/buttonBarButtonStyle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Cancel" /></LinearLayout></android.support.constraint.ConstraintLayout>

The FingerprintHelper.java class is where we define the methods for authentication and initialization of Fingerprint and related class objects:

在FingerprintHelper.java类中,我们定义了指纹和相关类对象的身份验证和初始化方法:

package com.journaldev.androidfingerprintapi;import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;public class FingerprintHelper extends FingerprintManager.AuthenticationCallback {private Context mContext;private FingerprintManager mFingerprintManager;private CancellationSignal mCancellationSignal;private Callback mCallback;public FingerprintHelper(FingerprintManager fingerprintManager, Context context, Callback callback) {mContext = context;mFingerprintManager = fingerprintManager;mCallback = callback;}public boolean isFingerprintAuthAvailable() {return mFingerprintManager.isHardwareDetected()&& mFingerprintManager.hasEnrolledFingerprints();}public void startAuthentication(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {if (!isFingerprintAuthAvailable())return;mCancellationSignal = new CancellationSignal();if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {return;}manager.authenticate(cryptoObject, mCancellationSignal, 0, this, null);}public void stopListening() {if (mCancellationSignal != null) {mCancellationSignal.cancel();mCancellationSignal = null;}}@Overridepublic void onAuthenticationError(int errMsgId, CharSequence errString) {mCallback.onError(errString.toString());}@Overridepublic void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {mCallback.onHelp(helpString.toString());}@Overridepublic void onAuthenticationFailed() {mCallback.onAuthenticated(false);}@Overridepublic void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {mCallback.onAuthenticated(true);}public interface Callback {void onAuthenticated(boolean b);void onError(String s);void onHelp(String s);}
}

manager.authenticate(cryptoObject, mCancellationSignal, 0, this, null); starts the authentication.

manager.authenticate(cryptoObject, mCancellationSignal, 0, this, null); 开始认证。

The Callback interface is used to pass the information to the UI which eventually gets displayed to the user.

回调接口用于将信息传递到UI,最终将其显示给用户。

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidfingerprintapi;import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {Button button;FingerprintManagerCompat managerCompat;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = findViewById(R.id.button);button.setOnClickListener(this);}private void showFingerPrintDialog() {FingerprintDialog fragment = new FingerprintDialog();fragment.setContext(this);fragment.show(getSupportFragmentManager(), "");}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button:managerCompat = FingerprintManagerCompat.from(MainActivity.this);if (managerCompat.isHardwareDetected() && managerCompat.hasEnrolledFingerprints()) {showFingerPrintDialog();} else {Toast.makeText(getApplicationContext(), "Fingerprint not supported", Toast.LENGTH_SHORT).show();}break;}}}

managerCompat = FingerprintManagerCompat.from(MainActivity.this); initialises the FingerprintCompat class object.

managerCompat = FingerprintManagerCompat.from(MainActivity.this); 初始化FingerprintCompat类对象。

isHardwareDetected() and hasEnrolledFingerprints() are used to check whether the fingerprint authentication is possible before showing the Dialog.

isHardwareDetected()hasEnrolledFingerprints()用于在显示对话框之前检查指纹身份验证是否可行。

The code for the FingerprintDialog.java is given below:

FingerprintDialog.java的代码如下:

package com.journaldev.androidfingerprintapi;import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;public class FingerprintDialog extends DialogFragmentimplements FingerprintHelper.Callback {Button mCancelButton;public static final String DEFAULT_KEY_NAME = "default_key";FingerprintManager mFingerprintManager;private FingerprintManager.CryptoObject mCryptoObject;private FingerprintHelper mFingerprintHelper;KeyStore mKeyStore = null;KeyGenerator mKeyGenerator = null;KeyguardManager mKeyguardManager;private Context mContext;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setRetainInstance(true);setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog);try {mKeyStore = KeyStore.getInstance("AndroidKeyStore");} catch (KeyStoreException e) {e.printStackTrace();}try {mKeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchProviderException e) {e.printStackTrace();}Cipher defaultCipher;try {defaultCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"+ KeyProperties.BLOCK_MODE_CBC + "/"+ KeyProperties.ENCRYPTION_PADDING_PKCS7);} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new RuntimeException("Failed to get an instance of Cipher", e);}mKeyguardManager = getContext().getSystemService(KeyguardManager.class);mFingerprintManager = getContext().getSystemService(FingerprintManager.class);mFingerprintHelper = new FingerprintHelper(mFingerprintManager, getContext(), this);if (!mKeyguardManager.isKeyguardSecure()) {Toast.makeText(getContext(),"Lock screen not set up.\n"+ "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint",Toast.LENGTH_LONG).show();return;}createKey(DEFAULT_KEY_NAME);if (initCipher(defaultCipher, DEFAULT_KEY_NAME)) {mCryptoObject = new FingerprintManager.CryptoObject(defaultCipher);}}private boolean initCipher(Cipher cipher, String keyName) {try {mKeyStore.load(null);SecretKey key = (SecretKey) mKeyStore.getKey(keyName, null);cipher.init(Cipher.ENCRYPT_MODE, key);return true;} catch (KeyPermanentlyInvalidatedException e) {Toast.makeText(mContext, "Keys are invalidated after created. Retry the purchase\n"+ e.getMessage(),Toast.LENGTH_LONG).show();return false;} catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException| NoSuchAlgorithmException | InvalidKeyException e) {Toast.makeText(mContext, "Failed to init cipher", Toast.LENGTH_LONG).show();return false;}}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View v = inflater.inflate(R.layout.dialog_fingerprint, container, false);mCancelButton = v.findViewById(R.id.btnCancel);mCancelButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {dismiss();}});return v;}@Overridepublic void onResume() {super.onResume();if (mCryptoObject != null) {mFingerprintHelper.startAuthentication(mFingerprintManager, mCryptoObject);}}@Overridepublic void onPause() {super.onPause();mFingerprintHelper.stopListening();}public void setContext(Context context) {mContext = context;}public void createKey(String keyName) {try {mKeyStore.load(null);KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keyName,KeyProperties.PURPOSE_ENCRYPT |KeyProperties.PURPOSE_DECRYPT).setBlockModes(KeyProperties.BLOCK_MODE_CBC).setUserAuthenticationRequired(true).setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);mKeyGenerator.init(builder.build());mKeyGenerator.generateKey();} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException| CertificateException | IOException e) {throw new RuntimeException(e);}}@Overridepublic void onAuthenticated(boolean b) {if (b) {Toast.makeText(mContext.getApplicationContext(), "Auth success", Toast.LENGTH_LONG).show();dismiss();} elseToast.makeText(mContext.getApplicationContext(), "Auth failed", Toast.LENGTH_LONG).show();}@Overridepublic void onError(String s) {Toast.makeText(mContext.getApplicationContext(), s, Toast.LENGTH_LONG).show();}@Overridepublic void onHelp(String s) {Toast.makeText(mContext.getApplicationContext(), "Auth help message:" + s, Toast.LENGTH_LONG).show();}
}

setRetainInstance(true); is used to prevent multiple instances of the DialogFragment from getting created when the config changes.

setRetainInstance(true); 用于防止在配置更改时创建DialogFragment的多个实例。

The output of the above application in action is given below:

上面应用程序的输出如下:

So on my phone when I authenticated with the correct fingerprint, it showed the appropriate Toast message.

因此,当我使用正确的指纹进行身份验证时,手机上会显示相应的Toast消息。

That brings an end to this tutorial. You can download the project from the link below:

这样就结束了本教程。 您可以从下面的链接下载项目:

AndroidFingerprintAPIAndroidFingerprintAPI
Github Project LinkGithub项目链接
Note: Fingerprint API is deprecated since API 28 and replaced by the BiometricPrompt. We’ll discuss that in another tutorial.注意 :自API 28开始不推荐使用指纹API,并由BiometricPrompt代替。 我们将在另一个教程中进行讨论。

翻译自: https://www.journaldev.com/23881/android-fingerprint-lock

android指纹解锁

android指纹解锁_Android指纹锁相关推荐

  1. 安卓系统的指纹解锁_安卓手机指纹解锁 手机指纹解锁怎么用 无良小偷的克星 好好玩...

    现在人都比较在乎空间和安全,安全就不用说了,不管什么的安全都特别在意,越安全越好.就拿手机来说,现在的人都离不开的一个物件,哪怕自己不小心把手机遗忘在什么地方,也不希望别人看到自己手机中的任何个人信息 ...

  2. iOS 指纹解锁 检测指纹信息变更

    通过LAContext evaluatedPolicyDomainState属性可以获取到当前data类型的指纹信息数据,当指纹增加或者删除,该data就会发生变化,通过记录这个TouchIdData ...

  3. android开发指纹解锁,Android-指纹解锁技术

    什么是指纹解锁技术 指纹解锁技术原理理解 指纹解锁技术的优势和缺点 在Android中的应用开发 什么是指纹解锁技术 根据人的指纹来验证是否能够解锁的技术,类似于通过输入密码来解锁,都是通过一定的数字 ...

  4. h5调用指纹识别_如何玩转指纹解锁H5插件?

    原标题:如何玩转指纹解锁H5插件? 科技发展到今天,生活中很多东西都被附上智能二字,手机.家电.家居.汽车等等很多方面,就连指纹也变得不一般了.指纹解锁最开始仅仅是在打卡签到上使用的,渐渐的人们保险安 ...

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

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

  6. android指纹解锁动画,Android8.1 SystemUI Keyguard之指纹解锁流程

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

  7. android流程点击开机键熄屏,一种基于android系统的灭屏状态下指纹解锁加速亮屏方法与流程...

    本发明涉及android系统解锁显示方法,尤其涉及一种基于android系统的灭屏状态下指纹解锁加速亮屏方法. 背景技术: 目前,随着指纹技术越来越普及,很多android系统设备都带有指纹外设,特别 ...

  8. Android 指纹识别(给应用添加指纹解锁)

    使用指纹 说明 : 指纹解锁在23 的时候,官方就已经给出了api ,但是由于Android市场复杂,无法形成统一,硬件由不同的厂商开发,导致相同版本的软件系统,搭载的硬件千变万化,导致由的机型不支持 ...

  9. wallpaper怎么设置锁屏_Apple ID密码忘了怎么找回?丨如何让面容和指纹解锁立马失效?...

    忘记Apple ID这种事肯定不少果粉都经历过,像小编也是如此,因为密码都比较复杂,如果太久没输入过密码,久而久之就忘了.哪一天突然需要用的时候,怎么想也想不起来.想不起来的话我们就别想了,直接重置密 ...

最新文章

  1. snabbdom源码解析(七) 事件处理
  2. 查看Oracle数据库SQL执行历史
  3. 经过不断努力 终于获得“推荐博客”的荣誉
  4. ipaddr库计算区间IP及CIDR的IP段
  5. 字符集之间转换(UTF-8,UNICODE,Gb2312) c++
  6. 【推荐】介绍两款Windows资源管理器,Q-Dir 与 FreeCommander XE(比TotalCommander更易用的免费资源管理器)...
  7. CodeForces - 766C - Mahmoud and a Message dp
  8. Atitit .h5文件上传
  9. 鸿蒙手机系统pc版下载,鸿蒙系统os下载官网版v1.0开源版
  10. RISC-V GCC工具链介绍
  11. 为何干电池是1.5v?而充电电池是1.2v?
  12. Application loader:ERROR ITMS-90168: The binary you uploaded was invalid.
  13. ICC2 user guide(四)Routing and Postroute Optimization
  14. 招募 | 香港理工大学Georg Kranz 博士诚招博士
  15. 文件上传流程和协议规范,简,全
  16. Linux——(1)基本命令
  17. 乐视腾讯深度合作 超级电视26日易迅网首发
  18. 2009年数学建模B题
  19. js读取excel或者导出成excel时权限设置问题
  20. 让你彻底搞懂IP地址

热门文章

  1. 什么是城府?你做到了你就无敌了!
  2. HNUST - 数据库课设
  3. HNUST 辅导上机(模拟)
  4. 会议室大屏幕用投影还是拼接屏好?
  5. 深读源码-java同步系列简介
  6. 同指数幂相减公式_指数幂的指数幂的运算法则
  7. 008-阈下意识|识别商场上的圈套
  8. Android 音频源码分析——音量调节流程
  9. 无情链表的创建,,插入,,删除第一个位
  10. B. Chris and Magic Square