指纹模块开发-FPW(M)指纹系列产品

开始

根据杭州蚁创科技有限公司《FPW(M)指纹系列产品开发手册》编写, 仅适用对应硬件,留作备忘。

在android6.0之后谷歌对指纹识别进行了官方支持,目前指纹领域无论从产品角度还是技术角度都已经趋于成熟,开发过程中遇到很多的问题,在此先按下不表。如果在没有指纹模块的安卓系统上进行指纹开发,就需要相应硬件的支持。于是采用了杭州蚁创科技有限公司的硬件。本篇博文内容也仅适应对应硬件。在这里抛砖引玉,希望能让大家开发时少走弯路。

使用

1. 添加权限:

指纹开发,硬件需要通过usb连接到安卓设备上。在此也需要将usb接口设置成host模式,不然的话无法进行识别。

<uses-feature android:name="android.hardware.usb.host"  android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

如果是安卓6.0以及以上系统,还需要动态获取权限。

2. 导入jar包和so文件

3. 愉快的使用

方法

  • 初始化设备
    public int Init();
    返回值参考常量
  • 关闭设备
    public int Close();
    返回值参考常量
  • SDK 版本
    public String GetVersion ();
  • 获取图像大小
    public int GetImageSize(int []pnWidth, int []pnHeight);
    pnWidth 图像宽度
    pnHeight 图像高度
    返回值参考常量
  • 检测手指
    public int DetectFinger(int[]isPressed)
    isPressed =0 手指抬起 =1 手指按下
    返回值参考常量
  • 上传原始图像
    public int GetImageRawData(byte[]pRawData);
    pRawData 图像大小 pnWidth*pnHeight
    返回值参考常量
  • 获取图像质量
    public int GetImageScore(byte[] pRawData,int nWidth, int nHeight);
    pRawData 图像大小 pnWidth*pnHeight
    pnScore 大于 IMAGE_SCORE 合格
    返回值参考常量
  • 将原始图像转换成 bmp
    public Bitmap ImageRawDataToBmp(byte[] pRawData, int nWidth, int
    nHeight);
  • 特征提取
    public int Extract(byte[] pRawData,int nWidth, int nHeight,byte[]
    pfeature);
    pRawData 图像大小 nWidth * nHeight
    pfeature 特征大小 FEATURE_LENTH
    返回值参考常量
  • 将三个特征转换成模板
    public int Enroll(byte[] pfeature1,byte[] pfeature2,byte[]
    pfeature3,byte[] pTemplate);
    pfeature1, pfeature2, pfeature3, pTemplate 大小 FEATURE_LENTH
    返回值参考常量
    一般将模板保存在后台数据库, 便于后期识别验证。FPW(M)指纹系列产品开发手册
    杭州蚁创科技有限公司
  • 指纹匹配
    public int Match(byte[] pfeature,byte[] pTemplate,int iLevel);
    两个特征相互匹配
    MATCH_LOW_LEVEL<=iLevel<= MATCH_HIGH_LEVEL,建议 3
    返回值参考常量
  • 搜索
    public int Search(byte[] pfeature1,byte[] pTemplate_n,int nTemplate);
    特征 pfeature1 大小 FEATURE_LENTH
    模 板 数 据 pTemplate_n 按 照 FTP_MAX_SIZE 的 长 度 累 计 长 度 为 nTemplate
    *FEATURE_LENTH
    模板个数 nTemplate
    返回成功的索引 pIndex
    最大个数 10000, 如果超过该限制, 与相关人员联系。

扩展

支付宝,腾讯等大厂都制定了自己的协议,标准直接和设备厂商合作,而应用方只有微信和支付宝自己。支付宝指纹支付标准是 IFAA ,腾讯的指纹支付标准是 SOTER,也就是说没有其他应用方会使用这个标准。所以很看应用方和设备厂商的协商程度。现在 IFAA 没有开源,只有 SOTER 是开源的了
如果接入,我们能省去兼容性测试的工作量,而且有些 6.0 以下的机型 SOTER 也支持。每个指纹将会有唯一 ID,也就是说,可以能把账号和指纹绑定起来,更加安全。
不过需要注意的是 SOTER 没支持华为等机型,而且以后机型的扩展受第三方支持的限制。

指纹开发常见问题

兼容问题

  1. 明明符合条件,isHardwareDetected() 返回 false?
    表现机型:MI 5s、vivo X9
    在同一机型上调用 FingerprintManagerCompat 的 isHardwareDetected() 和 hasEnrolledFingerprints() 时候,返回的都是 false,但是调用 FingerprintManager 的 isHardwareDetected()
    和 hasEnrolledFingerprints() 时,却是返回 true。
    解决:是否符合指纹条件可以多加一层判断。
  2. Letv X500 Android 6.0,API23 不按正常的套路回调
    onAuthenticationError 和 onAuthenticationFailed,理论上应该是识别失败的情况,但是该机型点击取消指纹识别也会先回调一次Error,如果遇到这种情况,只能根据具体项目环境中去进行规避适配了。
  3. 魅族上遇到的坑
    onAuthenticationHelp 回调不按套路出牌,正常官网文档解释,这个方法的回调时机是在指纹认证期间发生可恢复性的错误时回调。结果在魅族上,启动指纹识别认证的时候就会回调这个方法,里面传递回来的信息提示是“等待按下手指”,也就是说,它的 onAuthenticationHelp 回调跟官网时机不一样,而且方法的作用也变了,它在正常的情况回调了 onAuthenticationHelp。
    解决:不影响验证流程,无需解决
  4. 小米 锁屏和切后台生命周期不一致
    产品需求:用户锁屏或切到后台时(onStop)自动停止指纹验证,回到界面时(onResume)自动调起验证。
    所以我在指纹回调方法中加入了标志位 isInAuth。onStop时保存 isInAuth,onResume时 isInAuth == true 则自动调起验证。
      @Override
      public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
          isInAuth = false;
      }

      @Override
      public void onAuthenticationError(int errMsgId, CharSequence errString) {
          isInAuth = false;
      }

      @Override
      public void onAuthenticationFailed() {
          isInAuth = true;
      }

      @Override
      public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
          isInAuth = true;
      }

然而小米6、米mix2 锁屏时的生命周期是 onAuthenticationError -> onStop;切到后台是 onStop -> onAuthenticationError。导致不同流程下拿到 isInAuth 标志位不一致,无法自动调起验证。
解决:界面指纹按钮可以手动调起验证,无需兼容处理。
小米5生命周期同上,但是无论是自动还是手动调起验证,马上就回调了 onAuthenticationError,也就是说 MI5 从后台切回来后,指纹验证流程中断。
解决:用一个栈来存储调用方法顺序,如果验证方法调起,马上就回调 onAuthenticationError 方法,则判定是属于兼容问题,按验证失败来解决。
5. 密钥解密失败
三星SM-A9100 、Nexus 6P密钥解密失败
解决:暂无法解决

其他兼容解决方案:

三星passSdk(不过从2018下半年开始,Pass SDK 将不再提供 DEVICE_FINGERPRINT_UNIQUE_ID 。也就是不再为每个已注册的指纹提供索引了。因此将无法通过 SDK 区分使用哪个指纹来验证用户。)

魅族 flyme开发平台提供了指纹验证官方api

扫描二维码关注公众号,回复: 9051364 查看本文章

非兼容问题

  1. 新注册指纹密钥解密失败
    系统中注册了一个新的指纹的情况下,即使指纹在系统指纹列表里,验证也不通过。
    解决:删除了当前无效的key,然后根据参数再次生成密钥。

 @Override
        public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {      
        /**
         * doFinal方法会检查结果是不是会拦截或者篡改过,
         * 如果是的话会抛出一个异常,异常的时候都将认证当做是失败来处理
         */
        try {
            result.getCryptoObject().getCipher().doFinal();
            mCustomCallback.onAuthenticationSucceeded(true);
        } catch (IllegalBlockSizeException e) {
            //如果是新录入的指纹,会抛出该异常,需要重新生成密钥对重新验证,这里加个次数限制,避免进入验证异常->重新验证->又验证异常的死循环
            if (happenCount == 0) {
                beginAuthenticate();
                happenCount++;
                return;
            }
            mCustomCallback.onAuthenticationSucceeded(false);
        } catch (Exception e) {
            mCustomCallback.onAuthenticationSucceeded(false);
        }
       ...
    }
  1. 设备已有指纹,生成密钥却异常提示没有指纹
    非复现,和设备无关,怀疑是谷歌 API 的坑。
    java.lang.IllegalStateException: At least one fingerprint must be enrolled to create keys requiring user authentication for every use

解决:暂时只想到针对这个特定异常,直接使用无密钥验证,有一定的安全风险。

文章推荐

发布了70 篇原创文章 · 获赞 176 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zheng_weichao/article/details/86533763
今日推荐