Android Finger Identify (指紋識別) 完全實踐

大家可以關注我的AllAboutAndroid系列項目

導言

Android 6.0 之后開發(fā)指紋識別API,供開發(fā)者使用。其實在6.0之前就已經(jīng)有了指紋識別這一功能。Samsung手機幾乎在Android 4.2的時候就已經(jīng)在手機上有指紋識別的傳感器。各Android手機廠家為了競爭,也很早就加入了指紋識別這一功能。所以本文涉及的內(nèi)容就是:

  • Android 6.0及之后版本的指紋識別API實踐
  • Android Samsung 指紋識別API實踐
  • Android Meizu 指紋識別API實踐
    并將此指紋識別整合為SDK,供開發(fā)者使用。業(yè)務邏輯為:
FingerPass生成實例流程圖

Android M FingerManager API

注:本文只簡單解析API的最佳調(diào)用方式,并不涉及FingerPrintManger類的解析。
首先需要構造FingerPrintManger的實例,此方法必須在OS Version>=23才能執(zhí)行。需要權限USE_FINGERPRINT(已在Library 中配置)
控制FingerPrintManger指紋識別取消的是CancellationSignal類,所以構造此實例,用于取消指紋驗證操作。
指紋識別會有自己的Callback,為FingerprintManager.AuthenticationCallback。重寫三個方法即可:

  • onAuthenticationError 指紋識別的每一次錯誤都會回調(diào)到這個方法
  • onAuthenticationSucceeded 指紋識別認證成功調(diào)用此方法
  • onAuthenticationFailed 指紋識別認證失敗調(diào)用次方法
    此外,F(xiàn)ingerPrintManger還有三個方法需要注意:
  • isHardwareDetected 是否支持指紋識別
  • hasEnrolledFingerprints 是否注冊了指紋
  • authenticate 開始識別

其中authenticate方法有五個參數(shù),分別為CryptoObject,CancellationSignal, int, AuthenticationCallback, Handler。

  • CryptoObject 為加密對象,指紋識別過程數(shù)據(jù)被此CryptoObject加密,如果為null,則不會被加密
  • CancellationSignal 為取消信號
  • int flag 標志位,暫時默認為0
  • AuthenticationCallback 識別的Callback
  • Handler 指定Handler來處理指紋識別

關于AuthenticationCallback回調(diào)值,請看以下代碼:

        mAuthenticationCallback = new FingerprintManager.AuthenticationCallback() {
            @Override
            public void onAuthenticationError(int errorCode, CharSequence errString) {
                switch (errorCode) {
                    case FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE:
                        sendResult(FINGER_IDENTIFY_ERROR_HW_UNAVAILABLE);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
                        sendResult(FINGER_IDENTIFY_ERROR_UNABLE_TO_PROCESS);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_TIMEOUT:
                        sendResult(FINGER_IDENTIFY_ERROR_TIMEOUT);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_NO_SPACE:
                        sendResult(FINGER_IDENTIFY_ERROR_NO_SPACE);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_CANCELED:
                        sendResult(FINGER_IDENTIFY_ERROR_USER_CANCEL);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_LOCKOUT:
                        sendResult(FINGER_IDENTIFY_ERROR_LOCKOUT);
                        break;
                    default:
                        sendResult(FINGER_IDENTIFY_ERROR_OTHER);
                        break;
                }
            }
            @Override
            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
                sendResult(FINGER_IDENTIFY_SUCCESS);
            }

            @Override
            public void onAuthenticationFailed() {
                sendResult(FINGER_IDENTIFY_ERROR_AUTHENTIFICATION_FAILED);
            }
        };

Android Meizu FingerManager API

同F(xiàn)ingerPrintManger類類似,Meizu自己也寫了一個FingerPrintManger來處理指紋識別的事務,只不過API更為簡單。
魅族的FingerprintManager可以直接調(diào)用open()方法初始化FingerprintManager實例。
通過mFM.isSurpport() && mFM.isFingerEnable();來判斷是否支持指紋識別
查看是否已注冊指紋的方法是:mFM.getIds() != null
取消指紋識別:mFM.abort();
魅族指紋識別的Callback:FingerprintManager.IdentifyCallback 具體實現(xiàn)方法如下:

    private FingerprintManager.IdentifyCallback mIdentifyCallback = new FingerprintManager.IdentifyCallback() {
        @Override
        public void onIdentified(int i, boolean b) {
            mFM.release();
            sendResult(FINGER_IDENTIFY_SUCCESS);
        }

        @Override
        public void onNoMatch() {
            mFM.release();
            sendResult(FINGER_IDENTIFY_ERROR_AUTHENTIFICATION_FAILED);
        }
    };

開始指紋識別:mFM.startIdentify(mIdentifyCallback, mFM.getIds());

更詳細資料參見flyme文檔

Android Samsung Finger Spass API

三星的指紋識別比其他廠家復雜的多,需要用到兩個實例,一個是Spass,一個是SpassFingerprint。同樣需要兩個SDK,sdk-v1.0.0.jar, pass-v1.2.2.jar
首先是初始化實例:

        mSpass = new Spass();
        try {
            mSpass.initialize(mContext);
        } catch (Exception e) {
            isFingerEnable = false;
        }
        mSpassFingerprint = new SpassFingerprint(mContext);

注意一下,如果initialize方法拋異常的話,說明肯定不支持指紋驗證
所以說是否支持指紋驗證的方法就是:

    @Override
    public boolean isFingerIdentifyEnabled() {
        if (isFingerEnable){
            isFingerEnable = mSpass.isFeatureEnabled(Spass.DEVICE_FINGERPRINT);
        }
        return isFingerEnable;
    }

是否已注冊指紋: mSpassFingerprint.hasRegisteredFinger();
取消指紋驗證: mSpassFingerprint.cancelIdentify();
開始指紋驗證: mSpassFingerprint.startIdentify(mIdentifyListener);
指紋驗證CallBack:

    private IdentifyListener mIdentifyListener = new IdentifyListener() {
        @Override
        public void onFinished(int eventStatus) {
            Log.i("SamsungFinger", "eventStatus: " + eventStatus);
            switch (eventStatus) {
                case SpassFingerprint.STATUS_AUTHENTIFICATION_SUCCESS:
                case SpassFingerprint.STATUS_AUTHENTIFICATION_PASSWORD_SUCCESS:
                    sendResult(FINGER_IDENTIFY_SUCCESS);
                    break;
                case SpassFingerprint.STATUS_USER_CANCELLED:
                case SpassFingerprint.STATUS_USER_CANCELLED_BY_TOUCH_OUTSIDE:
                    sendResult(FINGER_IDENTIFY_ERROR_USER_CANCEL);
                    break;
                case SpassFingerprint.STATUS_TIMEOUT_FAILED:
                    sendResult(FINGER_IDENTIFY_ERROR_TIMEOUT);
                    break;
                case SpassFingerprint.STATUS_SENSOR_FAILED:
                    sendResult(FINGER_IDENTIFY_ERROR_HW_UNAVAILABLE);
                    break;
                case SpassFingerprint.STATUS_OPERATION_DENIED:
                    sendResult(FINGER_IDENTIFY_ERROR_LOCKOUT);
                    break;
                case SpassFingerprint.STATUS_AUTHENTIFICATION_FAILED:
                case SpassFingerprint.STATUS_QUALITY_FAILED:
                    sendResult(FINGER_IDENTIFY_ERROR_AUTHENTIFICATION_FAILED);
                    break;
                case SpassFingerprint.STATUS_BUTTON_PRESSED:
                default:
                    sendResult(FINGER_IDENTIFY_ERROR_OTHER);
                    break;
            }
        }
        @Override public void onReady() {}
        @Override public void onStarted() {}
        @Override public void onCompleted() {}
    };

實現(xiàn)方式

首先,我們已知的環(huán)境是有多種指紋識別的廠商SDK,而且這些廠商SDK最終的方法除了換了一個名字以外,實現(xiàn)的意義都是一樣的:

  • 是否支持指紋驗證
  • 是否已注冊指紋
  • 開始指紋驗證
  • 取消指紋驗證
    所以我們只需要定義好abstract基類BaseFingerInterpolator,以及返回接口FingerIdentifyCallBack和返回的resultCode就好了
    BaseFingerInterpolator:
public abstract class BaseFingerInterpolator {
    public final static int FINGER_IDENTIFY_SUCCESS = 0;
    public final static int FINGER_IDENTIFY_ERROR_USER_CANCEL = 1;
    public final static int FINGER_IDENTIFY_ERROR_HW_UNAVAILABLE = 2;
    public final static int FINGER_IDENTIFY_ERROR_UNABLE_TO_PROCESS = 3;
    public final static int FINGER_IDENTIFY_ERROR_TIMEOUT = 4;
    public final static int FINGER_IDENTIFY_ERROR_NO_SPACE = 5;
    public final static int FINGER_IDENTIFY_ERROR_LOCKOUT = 6;
    public final static int FINGER_IDENTIFY_ERROR_OTHER = 7;
    public final static int FINGER_IDENTIFY_ERROR_AUTHENTIFICATION_FAILED = 8;

    protected FingerIdentifyCallBack mCallBack;
    protected Context mContext;

    public BaseFingerInterpolator(Context context, FingerIdentifyCallBack callBack) {
        this.mCallBack = callBack;
        this.mContext = context;
    }

    protected void sendResult(int result){
        if (mCallBack != null){
            mCallBack.onIdentifyResult(result);
        }
    }

    public abstract boolean isFingerIdentifyEnabled();

    public abstract boolean hasEnrolledFingerprints();

    public abstract void startFingerPrints();

    public abstract void stopFingerPrints();
}

FingerIdentifyCallBack

public interface FingerIdentifyCallBack {
    void onIdentifyResult(int result);
}

剩下的就是每個類實現(xiàn)對應的SDK的方法就好了。

Demo

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容