Android 指纹识别 -- 基于Api23实现

Android指纹识别流程分析及功能实现

目录

搬运直接从3.实现效果开始看就行了

基础知识

1.概述

2.分析

3.实现效果

4.实现步骤

4.1-声明权限(AndroidManifest.xml)

4.2-帮助类、DialogFragment及资源导入

4.3-判断系统版本、是否拥有权限以及指纹识别模块是否可用

4.4-发起指纹识别及接受结果

参考文献


基础知识

Android App的指纹识别功能是基于系统录入的指纹,调用系统提供的Api发起识别并监听识别结果实现的,App并不能管理指纹(增加或删除)。

 

1.概述

Android 6.0(Android M Api23),Android 系统开放了指纹识别的api,存在于 android.hardware.fingerprint包下,核心类是FingerprintManager,提供了基础的指纹识别的功能。

FingerprintAndroid 9.0(Android P Api28)被添加了 @Deprecated 标记,Android 9.0官方推荐使用Biometric来进行安全认证。Google开发者文档中的介绍:

On devices running P and above, this will show a system-provided authentication prompt, using a device's supported biometric (fingerprint, iris, face, etc).

“在运行P及更高版本的设备上,这将显示系统提供的身份验证提示,并使用设备支持的生物特征识别(指纹,虹膜,面部等)”(目前只提供了指纹识别的Api)

也就是从Android 9.0开始安全认证弹窗统一使用系统提供的样式,开发者只能进行有限的调整(颜色和按钮文案)。

因为国内流行屏下指纹解锁,当使用Android 9.0 Api进行指纹识别时,会出现系统弹窗和厂家定制的指纹识别框重叠的问题,并且网传部分厂家定制的Android 9.0系统,调用Api28的识别方法时,即使录入过指纹也会返回错误提示未输入过指纹(eg:三星galaxynote8)。所以为了稳定性及兼容性,目前来说建议基于Api23实现指纹识别功能。(本篇方案于Android 9.0 的模拟器、真机(屏下指纹)和真机(指纹传感器)测试过,均可正常运行)

 

2.分析

基于Api23指纹识别流程图

Android 指纹识别 -- 基于Api23实现_第1张图片

authenticate方法说明

Android 指纹识别 -- 基于Api23实现_第2张图片

Android 指纹识别 -- 基于Api23实现_第3张图片

①. crypto这是一个加密类的对象,指纹扫描器会使用这个对象来判断认证结果的合法性。这个对象可以是null,但是这样的话,就意味这app无条件信任认证的结果,虽然从理论上这个过程可能被攻击,数据可以被篡改,这是app在这种情况下必须承担的风险。因此,建议这个参数不要置为null。这个类的实例化有点麻烦,主要使用javax的security接口实现,FingerprintRecognitionHelper类中有提供封装好的方法createCipher

②. cancel这个是CancellationSignal类的一个对象,这个对象用来在指纹识别器扫描用户指纹的是时候取消当前的扫描操作,如果不取消的话,那么指纹扫描器会移植扫描直到超时(一般为30s,取决于具体的厂商实现),这样的话就会比较耗电。建议这个参数不要置为null。

③. flags 标识位,根据上图的文档描述,这个位暂时应该为0,这个标志位应该是保留将来使用的。

④.callback这个是FingerprintManager.AuthenticationCallback类的对象,这个是这个接口中除了第一个参数之外最重要的参数了,稍后我们详细来介绍。这个参数不能为NULL。

⑤. handler 这是Handler类的对象,如果这个参数不为null的话,那么FingerprintManager将会使用这个handler中的looper来处理来自指纹识别硬件的消息。通常来讲,开发这不用提供这个参数,可以直接置为null,因为FingerprintManager会默认使用app的main looper来处理。

此处说明来自 Google开发者文档 与 https://www.jianshu.com/p/ae93a3722596 

 

3.实现效果

 

4.实现步骤

4.1-声明权限(AndroidManifest.xml)

 基于Api23实现指纹识别所需权限。

虽然该权限Google声明级别为NormalPermissions,但由于国内厂家定制原因,存在将该权限定为动态权限的定制系统,所以保守起见,使用前还是要确定拥有该权限。

4.2-帮助类、DialogFragment及资源导入

帮助类FingerprintRecognitionHelper:提供加密类对象创建方法,开始/停止指纹识别方法及识别结果回调监听方法。不想使用demo中封装好的指纹识别dialog时,可选择参考demo用法单独使用该帮助类进行指纹识别

封装好的FingerprintRecognitionDialog:基于封装好的帮助类实现的指纹识别弹窗,show则开启指纹识别,可通过回调监听识别结果

 缺少的资源文件,如DialogFragment的style、layout、指纹识别相关icon及提示string等,均已随demo上传至GitHub

布局样式及文案可根据实际情况自行替换,但指纹识别的icon,Google官方建议统一采用其提供的图标。Google官方指纹识别icon下载地址(同时也是官方demo地址)

4.3-判断系统版本、是否拥有权限以及指纹识别模块是否可用

        //指纹识别
        //1.判断系统版本是否高于等于6.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //2.确认拥有指纹识别权限--(虽然指纹权限为NormalPermissions,但国内部分厂商将此权限定为了危险权限,所以使用前先确定拥有该权限)
            mRequestPermissionHelper.requestPermissions(JavaMainActivity.this, 2, "获取指纹识别权限", new PermissionCallback() {
                @Override
                public void requestPermissionSuccess(int requestCode) {
                    //3.判断指纹识别功能是否可用
                    FingerprintRecognitionHelper.AvailableStatus availableStatus = FingerprintRecognitionHelper.getFingerprintAuthAvailable(JavaMainActivity.this);
                    switch (availableStatus) {
                        case NOT_HAVE:
                            //TODO 不存在指纹识别模块
                            break;
                        case NOT_LOCK:
                            //TODO 未启用指纹识别功能
                            break;
                        case NOT_ENTRY:
                            //TODO 未录入指纹
                            break;
                        case AVAILABLE:
                            //TODO 指纹识别可用
                            fingerprintAuthenticate();
                            break;
                    }
                }

                @Override
                public void requestPermissionFailed(int requestCode) {
                    //TODO 未授予指纹识别权限
                }
            }, Manifest.permission.USE_FINGERPRINT);
        }

指纹识别不可用有5种情况:

1.Api小于23;

2.无权限;

3.不存在指纹识别硬件;

4.未启用开屏密码(录入指纹的前提是系统有设置锁屏密码,所以无锁屏密码即表示指纹识别不可用);

5.未录入指纹。

(此处判断是否拥有权限及无权限时发起请求的步骤,采用了自己封装的帮助类,你们可以根据情况自行替换代码 。笔者所用帮助类:《Android 权限请求 -- 对开发者更友好的危险权限请求处理》)

4.4-发起指纹识别及接受结果

    private FingerprintRecognitionDialog mFingerprintRecognitionDialog;

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void fingerprintAuthenticate(){
        if (mFingerprintRecognitionDialog == null) {
            mFingerprintRecognitionDialog = new FingerprintRecognitionDialog();
            mFingerprintRecognitionDialog.setCallback(new FingerprintRecognitionDialog.Callback() {
                @Override
                public void onSuccess() {
                    //TODO 指纹识别成功
                    Toast.makeText(JavaMainActivity.this, "指纹识别成功", Toast.LENGTH_LONG).show();
                }

                @Override
                public void onFailure() {
                    //TODO 指纹识别失败,且30秒无法再进行指纹识别
                    Toast.makeText(JavaMainActivity.this, "指纹识别失败", Toast.LENGTH_LONG).show();
                }
            });
        }
        mFingerprintRecognitionDialog.show(getSupportFragmentManager(), JavaMainActivity.class.getSimpleName());
    }

当判断指纹识别为可用时,调用封装好的FingerprintRecognitionDialog发起指纹识别 

 

到此结束,如有更好的见解或建议,欢迎留言

Demo下载地址:https://github.com/ziwenL/FingerprintRecognitionDemo

Demo中存在JavaMainActivity与KotlinMainActivity,都是启用本文指纹识别功能的示例代码,只是所用语言不一样,逻辑及实现效果一致,可自行选择参阅

 

参考文献

  • Android Developers-fingerprint
  • Android Developers-FingerprintDialogDemo.
  • Android 指纹识别

 

你可能感兴趣的:(Android 指纹识别 -- 基于Api23实现)