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)在上文中提到了需要設置鎖屏,鎖屏之後,可以通過指紋解鎖啊,這個時候,如果應用中已經在等待用戶輸入指紋,再鎖屏並解鎖,發現返回應用之後,已經被取消了,原因同理,都是不能同時開啓兩次,會把上次的取消掉。