近期在做android指紋相關的功能,谷歌在android6.0及以上版本號對指紋識別進行了官方支持。當時在FingerprintManager和FingerprintManagerCompat這兩個之間糾結。當中使用FingerprintManager要引入com.android.support:appcompat-v7包。考慮到包的大小,決定使用v4兼容包FingerprintManagerCompat來實現。
主要實現的工具類FingerprintUtil:驗證手機是否支持指紋識別方法callFingerPrintVerify(),主要驗證手機硬件是否支持(6.0及以上),有沒有錄入指紋,然后有沒有開啟鎖屏password。開始驗證對於識別成功,失敗能夠進行對應的回調處理。
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(); } } /** * 是否錄入指紋,有些設備上即使錄入了指紋,可是沒有開啟鎖屏password的話此方法還是返回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; } } /** * 推斷是否開啟鎖屏password * * @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接口實現。