在android 6.0中google终于给android系统加上了指纹识别的支持,这个功能在iPhone上早就已经实现了,并且在很多厂商的定制的ROM中也都自己内部实现这个功能了,这个功能来的有点晚啊。在google全新发布的nexus设备:nexus 5x和nexus 6p中都携带了一颗指纹识别芯片在设备的背面,如下图(图片来自网络):
笔者手中的设备就是图上的那台黑色的nexus 5x,话说这台机器很是好看呢!手感超棒!
废话不多说,下面我出一个指纹识别的demo app,并且详细说明怎么开发一个基于google api的指纹识别app。demo的源码在我的github上:
https://github.com/CreateChance/AndroidFingerPrintDemo
Android M中的指纹识别接口
这个是首先需要关注的问题,在实际动手开始写app之前需要知道最新的平台为我们提供了那些指纹识别的接口。所有的指纹识别接口全部在android.hardware.fingerprint这个包下,这个包中的类不是很多,如下:
api doc链接地址:
https://developer.android.com/reference/android/hardware/fingerprint/package-summary.html
大家最好FQ自己看下。
上面的图中,我们看到这个包中总共有4个类,下面我们简要介绍一下他们:
1.FingerprintManager:主要用来协调管理和访问指纹识别硬件设备
2.FingerprintManager.AuthenticationCallback这个一个callback接口,当指纹认证后系统会回调这个接口通知app认证的结果是什么
3.FingerprintManager.AuthenticationResult这是一个表示认证结果的类,会在回调接口中以参数给出
4.FingerprintManager.CryptoObject这是一个加密的对象类,用来保证认证的安全性,这是一个重点,下面我们会分析。
好了,到这里我们简要知道了android 6.0给出的指纹识别的接口不是很多,可以说是简短干练。
动手开发一个指纹识别app
现在,我们要动手写一个利用上面接口的指纹识别app,这个app界面很简单,就一个activity,这个activity上会激活指纹识别,然后提示用户按下指纹,并且会将认证的结果显示出来。
开始
在开始之前,我们需要知道使用指纹识别硬件的基本步骤:
1.在AndroidManifest.xml中申明如下权限:
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
2.获得FingerprintManager的对象引用
3.在运行是检查设备指纹识别的兼容性,比如是否有指纹识别设备等。下面我们详细说一下上面的步骤:
申明权限
这一步比较简单,只要在AndroidManifest.xml中添加上面说到的权限就可以了。
获得FingerprintManager对象引用
这是app开发中获得系统服务对象的常用方式,如下:
// Using the Android Support Library v4
fingerprintManager = FingerprintManagerCompat.from(this);
// Using API level 23:
fingerprintManager = (FingerprintManager)getSystemService(Context.FINGERPRINT_SERVICE);
上面给出两种方式,第一种是通过V4支持包获得兼容的对象引用,这是google推行的做法;还有就是直接使用api 23 framework中的接口获得对象引用。
检查运行条件
要使得我们的指纹识别app能够正常运行,有一些条件是必须满足的。
1). API level 23
指纹识别API是在api level 23也就是android 6.0中加入的,因此我们的app必须运行在这个系统版本之上。因此google推荐使用 Android Support Library v4包来获得FingerprintManagerCompat对象,因为在获得的时候这个包会检查当前系统平台的版本。
2). 硬件
指纹识别肯定要求你的设备上有指纹识别的硬件,因此在运行时需要检查系统当中是不是有指纹识别的硬件:
if (!fingerprintManager.isHardwareDetected()) {
// no fingerprint sensor is detected, show dialog to tell user.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.no_sensor_dialog_title);
builder.setMessage(R.string.no_sensor_dialog_message);
builder.setIcon(android.R.drawable.stat_sys_warning);
builder.setCancelable(false);
builder.setNegativeButton(R.string.cancel_btn_dialog, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
// show this dialog.
builder.create().show();
}
调用上面的接口接可以知道系统中是不是有一个这样的硬件,如果没有的话,那就需要做一些合适的事情,比如提示用户当前系统中没有指纹识别硬件等。
3). 当前设备必须是处于安全保护中的
这个条件的意思是,你的设备必须是使用屏幕锁保护的,这个屏幕锁可以是password,PIN或者图案都行。为什么是这样呢?因为google原生的逻辑就是:想要使用指纹识别的话,必须首先使能屏幕锁才行,这个和android 5.0中的smart lock逻辑是一样的,这是因为google认为目前的指纹识别技术还是有不足之处,安全性还是不能和传统的方式比较的。
我们可以使用下面的代码检查当前设备是不是处于安全保护中的:
KeyguardManager keyguardManager =(KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager.isKeyguardSecure()) {
// this device is secure.
}
我们使用KeyguardManager的isKeyguardSecure接口就能知道。
4). 系统中是不是有注册的指纹
在android 6.0中,普通app要想使用指纹识别功能的话,用户必须首先在setting中注册至少一个指纹才行,否则是不能使用的。所以这里我们需要检查当前系统中是不是已经有注册的指纹信息了:
if (!fingerprintManager.hasEnrolledFingerprints()) {
// no fingerprint image has been enrolled.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.no_fingerprint_enrolled_dialog_title);
builder.setMessage(R.string.no_fingerprint_enrolled_dialog_message);
builder