1. 程式人生 > >android指紋識別開發

android指紋識別開發

android6.0之後google對指紋識別進行了官方支援。

相關類介紹

1.FingerprintManager:主要用來協調管理和訪問指紋識別硬體裝置
2.FingerprintManager.AuthenticationCallback這個一個callback介面,當指紋認證後系統會回撥這個介面通知app認證的結果是什麼
3.FingerprintManager.AuthenticationResult這是一個表示認證結果的類,會在回撥介面中以引數給出
4.FingerprintManager.CryptoObject這是一個加密的物件類。

需要的許可權

<uses-permission
android:name="android.permission.USE_FINGERPRINT"/>

獲取manger的幾種方式

// Using the Android Support Library v4
fingerprintManager = FingerprintManagerCompat.from(this);
// Using API level 23:
fingerprintManager = (FingerprintManager)getSystemService(Context.FINGERPRINT_SERVICE);

使用FingerprintManagerCompat可以直接繞過許可權(google推薦,api會幫我們做一些程式碼相容問題)
還有一個類FingerPrintManagerCompatApi23也能實現功能,FingerprintManagerCompat和FingerPrintManagerCompatApi23這兩個類也能實現到識別指紋的功能,但是也是有侷限的。一般識別功能這兩個類都能實現這個效果,但是需要API Level 23,如果達不到不會報錯,這些類會什麼都不做。

執行條件

1). API level 23
指紋識別API是在api level 23也就是android 6.0中加入的,因此我們的app必須執行在這個系統版本之上。因此google推薦使用 Android Support Library v4包來獲得FingerprintManagerCompat物件,因為在獲得的時候這個包會檢查當前系統平臺的版本。
2). 硬體
指紋識別肯定要求你的裝置上有指紋識別的硬體,因此在執行時需要檢查系統當中是不是有指紋識別的硬體:

fingerprintManager.isHardwareDetected()

3). 當前裝置必須是處於安全保護中的

KeyguardManager keyguardManager =(KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager.isKeyguardSecure()) {
    // this device is secure.
}

4). 系統中是不是有註冊的指紋

fingerprintManager.hasEnrolledFingerprints()

如果使用者還沒有註冊一個指紋的話,那麼我們的app可以提示使用者:如果想要使用指紋是功能,請再setting中註冊一個你的指紋。這裡需要囉嗦一句,如果你做過bluetooth或者其他裝置開發的話,那麼你知道你可以通過傳送一個intent來啟動bluetooth開啟的介面,只要是聲明瞭藍芽的管理許可權。但是,到目前位置google任然沒有開放讓普通app啟動指紋註冊介面的許可權

指紋驗證

不管使用FingerprintManagerCompat還是FingerprintManager,都用authenticate方法去驗證,引數說明:
1. crypto這是一個加密類的物件,指紋掃描器會使用這個物件來判斷認證結果的合法性。這個物件可以是null,但是這樣的話,就意味這app無條件信任認證的結果,雖然從理論上這個過程可能被攻擊,資料可以被篡改,這是app在這種情況下必須承擔的風險。因此,建議這個引數不要置為null。這個類的例項化有點麻煩,主要使用javax的security介面實現。
2. cancel 這個是CancellationSignal類的一個物件,這個物件用來在指紋識別器掃描使用者指紋的是時候取消當前的掃描操作,如果不取消的話,那麼指紋掃描器會移植掃描直到超時(一般為30s,取決於具體的廠商實現),這樣的話就會比較耗電。建議這個引數不要置為null。
3. flags 標識位,根據上圖的文件描述,這個位暫時應該為0,這個標誌位應該是保留將來使用的。
4. callback 這個是FingerprintManager.AuthenticationCallback類的物件,這個是這個介面中除了第一個引數之外最重要的引數了。當系統完成了指紋認證過程(失敗或者成功都會)後,會回撥這個物件中的介面,通知app認證的結果。這個引數不能為NULL。
5. handler 這是Handler類的物件,如果這個引數不為null的話,那麼FingerprintManager將會使用這個handler中的looper來處理來自指紋識別硬體的訊息。通常來講,開發這不用提供這個引數,可以直接置為null,因為FingerprintManager會預設使用app的main looper來處理。
注:使用CancellationSignal類取消驗證後,再使用authenticate就無效,除非重新進入app

FingerprintManager.AuthenticationCallback類:
1. OnAuthenticationError(int errorCode, ICharSequence errString) 這個介面會再系統指紋認證出現不可恢復的錯誤的時候才會呼叫,並且引數errorCode就給出了錯誤碼,標識了錯誤的原因。這個時候app能做的只能是提示使用者重新嘗試一遍。
2. OnAuthenticationFailed() 這個介面會在系統指紋認證失敗的情況的下才會回撥。注意這裡的認證失敗和上面的認證錯誤是不一樣的,雖然結果都是不能認證。認證失敗是指所有的資訊都採集完整,並且沒有任何異常,但是這個指紋和之前註冊的指紋是不相符的;但是認證錯誤是指在採集或者認證的過程中出現了錯誤,比如指紋感測器工作異常等。也就是說認證失敗是一個可以預期的正常情況,而認證錯誤是不可預期的異常情況。
3. OnAuthenticationHelp(int helpMsgId, ICharSequence helpString) 上面的認證失敗是認證過程中的一個異常情況,我們說那種情況是因為出現了不可恢復的錯誤,而我們這裡的OnAuthenticationHelp方法是出現了可以回覆的異常才會呼叫的。什麼是可以恢復的異常呢?一個常見的例子就是:手指移動太快,當我們把手指放到感測器上的時候,如果我們很快地將手指移走的話,那麼指紋感測器可能只採集了部分的資訊,因此認證會失敗。但是這個錯誤是可以恢復的,因此只要提示使用者再次按下指紋,並且不要太快移走就可以解決。
4. OnAuthenticationSucceeded(FingerprintManagerCompati.AuthenticationResult result)這個介面會在認證成功之後回撥。我們可以在這個方法中提示使用者認證成功。這裡需要說明一下,如果我們上面在呼叫authenticate的時候,我們的CryptoObject不是null的話,那麼我們在這個方法中可以通過AuthenticationResult來獲得Cypher物件然後呼叫它的doFinal方法。doFinal方法會檢查結果是不是會攔截或者篡改過,如果是的話會丟擲一個異常。當我們發現這些異常的時候都應該將認證當做是失敗來來處理,為了安全建議大家都這麼做。

  public class MyCallBack extends FingerprintManagerCompat.AuthenticationCallback {
        private static final String TAG = "MyCallBack";

        // 當出現錯誤的時候回撥此函式,比如多次嘗試都失敗了的時候,errString是錯誤資訊
        @Override
        public void onAuthenticationError(int errMsgId, CharSequence errString) {
            Log.d(TAG, "onAuthenticationError: " + errString);
        }

        // 當指紋驗證失敗的時候會回撥此函式,失敗之後允許多次嘗試,失敗次數過多會停止響應一段時間然後再停止sensor的工作
        @Override
        public void onAuthenticationFailed() {
            Log.d(TAG, "onAuthenticationFailed: " + "驗證失敗");
        }

        @Override
        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
            Log.d(TAG, "onAuthenticationHelp: " + helpString);
        }

        // 當驗證的指紋成功時會回撥此函式,然後不再監聽指紋sensor
        @Override
        public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult
                                                      result) {
            Log.d(TAG, "onAuthenticationSucceeded: " + "驗證成功");
        }
    }