Android硬件開發系列一指紋識別

Android6.0系統纔開始支持指紋識別,不過也有些手機定製rom過早就提供相關api來支持,這裏不展開,主要從如下幾個方面介紹。

  • 兼容性介紹

    1、Api兼容性
    既然是高版本纔有的Api,那必須要兼容低版本使用了, Android.support.v4包中提供了兼容Api:FingerprintManagerCompat,其實現很簡單就是做了下api版本判斷,對於低版本的系統提供了空實現,如下:

static final FingerprintManagerCompatImpl IMPL;
      static {
        final int version = Build.VERSION.SDK_INT;
        if (version >= 23) {
            IMPL = new Api23FingerprintManagerCompatImpl();
        } else {
            IMPL = new LegacyFingerprintManagerCompatImpl();
        }
    }
    在LegacyFingerprintManagerCompatImpl中全部是空實現:
     private static class LegacyFingerprintManagerCompatImpl
            implements FingerprintManagerCompatImpl {

        public LegacyFingerprintManagerCompatImpl() {
        }

        @Override
        public boolean hasEnrolledFingerprints(Context context) {
            return false;
        }

        @Override
        public boolean isHardwareDetected(Context context) {
            return false;
        }

        @Override
        public void authenticate(Context context, CryptoObject crypto, int flags,
                CancellationSignal cancel, AuthenticationCallback callback, Handler handler) {
            // TODO: Figure out behavior when there is no fingerprint hardware available
        }
    }

對於強迫症而言,要求控制項目大小的話,不希望因爲這個API就要導入V4,個人直接抽離了這個V4中的兼容實現,直接一個類解決問題。

2、真機適配現狀
真機測試在多個品牌手機上發現都運行良好,沒有出現特別機型不適配,運行情況不統一現象,說明各個廠商良心發現啊,沒有給我帶來太多的適配問題,這也是硬件開發中最頭疼的事情。

  • Api使用細節

    1、檢查工作
    對於硬件設備使用來說,檢查工作少不了啊,直接貼代碼:

 FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(this);
        //首先檢查硬件設備-指紋識別是否支持
        if (!fingerprintManager.isHardwareDetected()) {
            Snackbar.make(getWindow().getDecorView(), "設備不支持指紋識別", Snackbar.LENGTH_LONG).show();
            return;
        }

        //安全性檢查,只要少一樣都用不起來,認爲必須要求有屏幕鎖
        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        if (!keyguardManager.isKeyguardSecure()) {
            Snackbar.make(getWindow().getDecorView(), "設備沒有屏幕鎖", Snackbar.LENGTH_LONG).show();
            return;
        }
        //是否設置了指紋
        if (!fingerprintManager.hasEnrolledFingerprints()) {
            Snackbar.make(getWindow().getDecorView(), "你還沒有設置指紋", Snackbar.LENGTH_LONG).show();
            return;
        }

當然還要檢查的一項就是權限檢查,如何申請權限不展開了哈。

android.permission.USE_FINGERPRINT

2、開始進行指紋識別

public static void startFingerPrintConfirm(Context context, CancellationSignal cancellationSignal,  AuthenticationCallBackCompact operator) throws Exception {
        FingerprintManagerCompat fingerprintManagerCompat = FingerprintManagerCompat.from(context);
        CryptoObjectHelper cryptoObjectHelper = new CryptoObjectHelper();//有利於識別cancellationSignal
        fingerprintManagerCompat.authenticate(cryptoObjectHelper.buildCryptoObject(), 0, cancellationSignal, operator, null);
    }
    //最終調用接口
    authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
            int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler)
     其中AuthenticationCallback 不可爲null,指紋識別開啓之後,可以聯繫識別5次,若5次都Fail,則回調Error 

3、注意事項,踏過的坑

1)其中CryptoObject crypto是可以爲null,但是這個建議最好要實現一個加密的對象,有利於在使用到CancellationSignal 對象時候,用來取消當前已開啓識別的進程。例如個人項目中就出現在一次已經開啓了指紋識別中,用戶需要關閉這個識別功能,但是爲了安全只能是用戶本人指紋驗證過後來關閉這個功能,故此時又要開啓另一個頁面來驗證指紋,這時候若沒有加密的對象話,會導致第二次開啓不了,因爲crypto是和每次call關聯,同時開啓第二次手機會自動把第一次的關閉,執行第一次的cancel.cancel()方法,導致第二次無故躺槍被認爲了已經取消了,啓動不了。

2)針對如上1)場景即使生成了crypto,還會有一個新問題(此時心裏1萬個草泥馬奔騰),由於手機會自動把第一次的關閉,取消上次操作,倒好直接回調第一次的取消的監聽,告訴你被取消了。但是還回調一次AuthenticationCallback.onAuthenticationError()並且是在第二次調用中的新對象的回調裏面,按道理如果這裏不共用回調對象AuthenticationCallback,也是在第一個對象中回調啊。這個失敗回調導致流程打亂了,其實這時候已經重新開啓了,這不是把流程干擾了嗎,糾結好久,用多種方式來判斷,這個時候的回調不處理,總覺得不夠完美,後想到了一個辦法,在開啓第二次時候,先把第一次的啓動主動cancel掉,然後再啓動第二次,當時覺得這個辦法好,可是還是一樣的情況,後來發現必須要間隔一段時間。

3)在上文中提到了需要設置鎖屏,鎖屏之後,可以通過指紋解鎖啊,這個時候,如果應用中已經在等待用戶輸入指紋,再鎖屏並解鎖,發現返回應用之後,已經被取消了,原因同理,都是不能同時開啓兩次,會把上次的取消掉。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章