Android 6.0 之后Google官方推出了指纹识别,但是很多厂商在6.0之前就有了指纹识别这一功能,这就涉及到了适配问题,不可能抛弃6.0之前的用户。

1,先介绍6.0之后的指纹识别的使用,虽然很简单,但也有几个坑。这里有两种方法获取到指纹对象。
FingerprintManager mManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
FingerprintManagerCompat mManager = FingerprintManagerCompat.from(this);

一开始我以为用哪个都可以,反正只是兼容6.0以上的,但在使用第一种的时候在6.0以下就会崩溃,使用try catch都没用,在我的印象里try catch应该是能否捕获所有的异常,但不知为什么就没有捕获到这个ClassNotFoundException,不知有没有知道为什么的,希望给个提示,虽然可以先判断版本,但我怕特殊机型会出问题,就使用了兼容包里的FingerprintManagerCompat,但万万没想到,不好使,监听没有回掉,判断返回都是false,这弄的我很是诧异,偶然间发现当兼容包v4 v7 包依赖为25.0.0时是好使的,所以没办法只能是回滚了,这里还有一个需要注意的东西,项目中类库的包的兼容包依赖版本不能高于项目中的。

2,兼容三星的指纹识别
http://developer.samsung.com/galaxy/pass# 可以在这个地址中下载三星指纹识别需要的sdk,通过使用他的demo,可以很容易的容,在后面代码中会介绍几个常用的方法。三星给了自己的指纹识别dialog,而google并没有给指纹识别的界面,开发时因为时间原因就没有找怎么更改他给的dialog。而其他的则是模仿ios的指纹提示页面。还有我原以为6.0之后用google的就会好使,但没想到有的三星手机升级6.0之后并不好使,没有直接6.0系统的三星手机,所以就只能判断以下版本在判断以下有三星的sdk是否好使了,不好使在用google的方法。

3,兼容魅族手机
http://open-wiki.flyme.cn/index.php?title=%E6%8C%87%E7%BA%B9%E8%AF%86%E5%88%ABAPI 可以在这个地址中下载魅族手机指纹识别需要的sdk,这个就比较简单了,6.0以下使用这个,6.0以上使用官方的,但不知为什么没有api介绍,难道是我没有找到?里面有两个方法让我很是纠结不知那个是判断是否支持指纹,也没有那么多的测试机。

FingerprintManager open = FingerprintManager.open();
open.isSurpport()
open.isFingerEnable()

4,代码:

/**
     * 判断能否使用指纹
     */
    public boolean canUseFingerprint() {
        //判断是否是三星手机而且可使用指纹
        if (InfoUtil.getBrandName().equals("samsung")) {//判断是否是三星手机
            if (FingerPrintUtil.get().isSamsungCanUseFingerPrint(this)) {
                return true;
            } else {
                return false;
            }
        } else if (InfoUtil.getBrandName().equals("Meizu")
                && InfoUtil.getSDKVersionNumber() < Build.VERSION_CODES.M) {//判断是否是魅族手机
            if(FingerPrintUtil.get().isMeizuCanUseFingerPrint()){
                return true;
            }else{
                return false;
            }
        } else {
            if (InfoUtil.getSDKVersionNumber() >= Build.VERSION_CODES.M) {
                try {
                    //捕获异常是否有FingerprintManager这个类
//                    FingerprintManager mFingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
                    FingerprintManagerCompat mFingerprintManager = FingerprintManagerCompat.from(this);
                    boolean hardwareDetected = mFingerprintManager.isHardwareDetected();
                    if (hardwareDetected) {
                        return true;
                    }
                } catch (Exception e) {
                    return false;
                }
            }
        }
        return false;
    }
/**
     * BrandName
     * @return
     */
    public static String getBrandName(){

        String brand = android.os.Build.BRAND;
        if (brand == null || brand.length() <= 0) {
            return "";
        } else {
            return brand;
        }
    }

public class FingerPrintUtil {

    private static FingerPrintUtil sFingerPrintUtil;

    public static  FingerPrintUtil get(){
        if(sFingerPrintUtil==null) {
            sFingerPrintUtil = new FingerPrintUtil();
        }
        return sFingerPrintUtil;
    }
    public boolean isSamsungCanUseFingerPrint(Context context){
            Spass mSpass = new Spass();
            try {
                mSpass.initialize(context);
                boolean isFeatureEnabled_fingerprint = mSpass.isFeatureEnabled(Spass.DEVICE_FINGERPRINT);
                //判断是否可用指纹
                if(isFeatureEnabled_fingerprint){
                    return true;
                }else{
                    return false;
                }
            } catch (SsdkUnsupportedException e) {
//                log("Exception: " + e);
            } catch (UnsupportedOperationException e) {
//                log("Fingerprint Service is not supported in the device");
            }
        return false;
    }

    public boolean hasSetSamsungFingerPrint(Context context){
        SpassFingerprint mSpassFingerprint = new SpassFingerprint(context);
        boolean hasEnrolledFingerprints = mSpassFingerprint.hasRegisteredFinger();
        return hasEnrolledFingerprints;
    }

    public boolean isMeizuCanUseFingerPrint(){
        try {
            FingerprintManager open = FingerprintManager.open();
            if (open.isFingerEnable() && open.isSurpport()) {
                return true;
            } else {
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }

    public boolean hasMeizuSetFingerprint(){
        try {
            FingerprintManager open = FingerprintManager.open();
            if(open.getIds()==null){
                return false;
            }else{
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }
}

google的指纹监听回掉的使用方法这个网上介绍很多,就不多做注释了:

mCancellationSignal = new CancellationSignal();
        mManager.authenticate(null, 0, mCancellationSignal, new FingerprintManagerCompat.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errMsgId, CharSequence errString) {
                super.onAuthenticationError(errMsgId, errString);
                mFingerprintHint.setText(errString);
                if (errString.equals("指纹操作已取消。")) {
                    cancelFingerPrintDialog();
                }
            }

            @Override
            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                super.onAuthenticationHelp(helpMsgId, helpString);
                mFingerprintHint.setText(helpString);
            }

            @Override
            public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
                super.onAuthenticationSucceeded(result);
                cancelFingerPrintDialog();
                requestUserInfo();
            }

            @Override
            public void onAuthenticationFailed() {
                super.onAuthenticationFailed();
                mFingerprintHint.setText("再试一次");
            }
        }, null);

samsung的指纹识别回掉:

package com.yibairun.presenter;

import android.content.Context;

import com.samsung.android.sdk.pass.Spass;
import com.samsung.android.sdk.pass.SpassFingerprint;
import com.yibairun.contract.FingerPrintContract;

/**
 * Created by zhangqingbin on 2017/3/8.
 */

public class SamsungFingerprintImpl {

    private final SpassFingerprint mSpassFingerprint;
    private final Spass mSpass;
    private final Context context;
    private final FingerPrintContract.OnSamsungFingerPrintCallBack callBack;
    private boolean onReadyIdentify;

    public SamsungFingerprintImpl(Context context, SpassFingerprint spassFingerprint, Spass spass, FingerPrintContract.OnSamsungFingerPrintCallBack callBack) {
        this.mSpassFingerprint = spassFingerprint;
        this.mSpass = spass;
        this.context = context;
        this.callBack=callBack;
    }

    private SpassFingerprint.IdentifyListener mIdentifyListenerDialog = new SpassFingerprint.IdentifyListener() {
        @Override
        public void onFinished(int eventStatus) {
//            log("identify finished : reason =" + getEventStatusName(eventStatus));
            int FingerprintIndex = 0;
            boolean isFailedIdentify = false;
            onReadyIdentify = false;
            try {
                FingerprintIndex = mSpassFingerprint.getIdentifiedFingerprintIndex();
            } catch (IllegalStateException ise) {
//                log(ise.getMessage());
            }
            if (eventStatus == SpassFingerprint.STATUS_AUTHENTIFICATION_SUCCESS) {
                callBack.onPrintSuccess();
//                log("onFinished() : Identify authentification Success with FingerprintIndex : " + FingerprintIndex);
            } else if (eventStatus == SpassFingerprint.STATUS_AUTHENTIFICATION_PASSWORD_SUCCESS) {
//                log("onFinished() : Password authentification Success");
            } else if (eventStatus == SpassFingerprint.STATUS_USER_CANCELLED
                    || eventStatus == SpassFingerprint.STATUS_USER_CANCELLED_BY_TOUCH_OUTSIDE) {
//                log("onFinished() : User cancel this identify.");
            } else if (eventStatus == SpassFingerprint.STATUS_TIMEOUT_FAILED) {
//                log("onFinished() : The time for identify is finished.");
                callBack.onPrintFailed("识别失败");
            } else if (!mSpass.isFeatureEnabled(Spass.DEVICE_FINGERPRINT_AVAILABLE_PASSWORD)) {
                if (eventStatus == SpassFingerprint.STATUS_BUTTON_PRESSED) {
//                    log("onFinished() : User pressed the own button");
//                    Toast.makeText(mContext, "Please connect own Backup Menu", Toast.LENGTH_SHORT).show();
                }
            } else {
//                log("onFinished() : Authentification Fail for identify");
                isFailedIdentify = true;
            }
//            if (!isFailedIdentify) {
//                resetIdentifyIndexDialog();
//            }
        }

        @Override
        public void onReady() {
//            log("identify state is ready");
        }

        @Override
        public void onStarted() {
//            log("User touched fingerprint sensor");
        }

        @Override
        public void onCompleted() {
//            log("the identify is completed");
        }
    };

    public void startIdentifyDialog(boolean backup) {
        if (onReadyIdentify == false) {
            onReadyIdentify = true;
            try {
                if (mSpassFingerprint != null) {
//                    setIdentifyIndexDialog();
                    mSpassFingerprint.startIdentifyWithDialog(context, mIdentifyListenerDialog, backup);
                }
            } catch (IllegalStateException e) {
                onReadyIdentify = false;
//                resetIdentifyIndexDialog();
//                log("Exception: " + e);
            }
        } else {
//            log("The previous request is remained. Please finished or cancel first");
        }
    }
}

魅族的指纹识别回掉:

package com.yibairun.presenter;

import com.fingerprints.service.FingerprintManager;
import com.yibairun.contract.FingerPrintContract;

/**
 * Created by zhangqingbin on 2017/3/9.
 */

public class MeizuFingerprintImpl  {

    private final FingerPrintContract.OnMeizuFingerPrintCallBack callBack;
    private FingerprintManager.IdentifyCallback mIdentifyCallback;

    public MeizuFingerprintImpl(FingerPrintContract.OnMeizuFingerPrintCallBack callBack) {
        this.callBack=callBack;
    }

    FingerprintManager mFM;
    private void initFingPrintManager() {
        if (mFM == null) {
            mFM = FingerprintManager.open(); //调用open方法得到FingerprintManager
        }
    }

    public void startVerify() {
        initFingPrintManager(); //得到FingerprintManager实例
        if (mFM.getIds() == null) { //得到系统中已经录入的指纹个数
            return;
        }
        if (mIdentifyCallback == null) {
            //创建指纹认证回调函数
            mIdentifyCallback = createIdentifyCallback();
        }

        mFM.startIdentify(mIdentifyCallback, mFM.getIds()); //调用指纹认证接口
    }

    private FingerprintManager.IdentifyCallback createIdentifyCallback() {
        return new FingerprintManager.IdentifyCallback() {

            @Override
            public void onIdentified(int id, boolean updated) { //认证成功
                callBack.onMeizuPrintSuccess();
                mFM.release(); //认证成功后release, 需要注意的是在不使用指纹功能后必须要调用release, 也就是说open和release严格配对
                //否则会造成mBack不能使用, 因为只有调用release之后才能从指纹模式切换到back模式
            }

            @Override
            public void onNoMatch() { //认证失败
//                Log.d(TAG, "onNoMatch! ");
                callBack.onMeizuPrintFailed("认证失败");
                startVerify(); //一次认证失败后重新再次发起认证
            }
        };
    }
}

后续如果有测试机就会尝试兼容其他种类手机,并且补充这篇文章