首页 > 代码库 > Android6.0指纹识别开发

Android6.0指纹识别开发

最近在做android指纹相关的功能,谷歌在android6.0及以上版本对指纹识别进行了官方支持。当时在FingerprintManager和FingerprintManagerCompat这两个之间纠结,其中使用FingerprintManager要引入com.android.support:appcompat-v7包,考虑到包的大小,决定使用v4兼容包FingerprintManagerCompat来实现。

主要实现的工具类FingerprintUtil:验证手机是否支持指纹识别方法callFingerPrintVerify(),主要验证手机硬件是否支持(6.0及以上),有没有录入指纹,然后有没有开启锁屏密码,开始验证对于识别成功,失败可以进行相应的回调处理。

 public class FingerprintUtil{

    private FingerprintManagerCompat mFingerprintManager;
    private KeyguardManager mKeyManager;
    private CancellationSignal mCancellationSignal;
    private Activity mActivity;

    public FingerprintUtil(Context ctx) {
        mActivity = (Activity) ctx;
        mFingerprintManager = FingerprintManagerCompat.from(mActivity);
        mKeyManager = (KeyguardManager) mActivity.getSystemService(Context.KEYGUARD_SERVICE);

    }

    public void callFingerPrintVerify(final IFingerprintResultListener listener) {
        if (!isHardwareDetected()) {
            return;
        }
        if (!isHasEnrolledFingerprints()) {
            if (listener != null) {
                listener.onNoEnroll();
            }
            return;
        }
        if (!isKeyguardSecure()) {
            if (listener != null) {
                listener.onInSecurity();
            }
            return;
        }
        if (listener != null) {
            listener.onSupport();
        }

        if (listener != null) {
            listener.onAuthenticateStart();
        }
        if (mCancellationSignal == null) {
            mCancellationSignal = new CancellationSignal();
        }
        try {
            mFingerprintManager.authenticate(null, 0, mCancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() {
                //多次尝试都失败会走onAuthenticationError,会停止响应一段时间,提示尝试次数过多,请稍后再试。
                @Override
                public void onAuthenticationError(int errMsgId, CharSequence errString) {
                    if (listener != null)
                        listener.onAuthenticateError(errMsgId, errString);
                }

                //指纹验证失败走此方法,例如小米前4次验证失败走onAuthenticationFailed,第5次走onAuthenticationError
                @Override
                public void onAuthenticationFailed() {
                    if (listener != null)
                        listener.onAuthenticateFailed();
                }

                @Override
                public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                    if (listener != null)
                        listener.onAuthenticateHelp(helpMsgId, helpString);

                }

                //当验证的指纹成功时会回调此函数,然后不再监听指纹sensor
                @Override
                public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                    if (listener != null)
                        listener.onAuthenticateSucceeded(result);
                }

            }, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 是否录入指纹,有些设备上即使录入了指纹,但是没有开启锁屏密码的话此方法还是返回false
     *
     * @return
     */
    private boolean isHasEnrolledFingerprints() {
        try {
            return mFingerprintManager.hasEnrolledFingerprints();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 是否有指纹识别硬件支持
     *
     * @return
     */
    public boolean isHardwareDetected() {
        try {
            return mFingerprintManager.isHardwareDetected();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否开启锁屏密码
     *
     * @return
     */
    private boolean isKeyguardSecure() {
        try {
            return mKeyManager.isKeyguardSecure();
        } catch (Exception e) {
            return false;
        }

    }

    /**
     * 指纹识别回调接口
     */
    public interface IFingerprintResultListener {
        void onInSecurity();

        void onNoEnroll();

        void onSupport();

        void onAuthenticateStart();

        void onAuthenticateError(int errMsgId, CharSequence errString);

        void onAuthenticateFailed();

        void onAuthenticateHelp(int helpMsgId, CharSequence helpString);

        void onAuthenticateSucceeded(FingerprintManagerCompat.AuthenticationResult result);

    }

    public void cancelAuthenticate() {
        if (mCancellationSignal != null) {
            mCancellationSignal.cancel();
            mCancellationSignal = null;
        }
    }


    public void onDestroy() {
        cancelAuthenticate();
        mKeyManager = null;
        mFingerprintManager = null;

    }

参考了一些资料,做了一些验证,得到一些结论:

1、当指纹识别失败后,会调用onAuthenticationFailed()方法,这时候指纹传感器并没有关闭,谷歌原生系统给了我们5次重试机会,也就是说,连续调用了4次onAuthenticationFailed()方法后,第5次会调用onAuthenticateError(int errMsgId, CharSequence errString)方法,此时errMsgId==7。
2、每次重新授权,哪怕不去校验,取消时会走onAuthenticateError(int errMsgId, CharSequence errString) 方法,其中errMsgId==5,
3、当系统调用了onAuthenticationError()和onAuthenticationSucceeded()后,传感器会关闭,只有我们重新授权,再次调用authenticate()方法后才能继续使用指纹识别功能。
4、兼容android6.0以下系统的话,不要使用FingerprintManagerCompat, 低于M的系统版本,FingerprintManagerCompat无论手机是否有指纹识别模块,均认为没有指纹识别,可以用FingerprintManager来做。
5、考虑到安全因素,最好authenticate(CryptoObject crypto, CancellationSignal cancel, int flags, AuthenticationCallback callback, Handler handler)时加入CryptoObject 。crypto这是一个加密类的对象,指纹扫描器会使用这个对象来判断认证结果的合法性。这个对象可以是null,但是这样的话,就意味着app无条件信任认证的结果,这个过程可能被攻击,数据可以被篡改,这是app在这种情况下必须承担的风险。因此,建议这个参数不要置为null。这个类的实例化有点麻烦,主要使用javax的security接口实现。
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    Android6.0指纹识别开发