Android指紋登錄

1、介紹

指紋登錄可以實現(xiàn)應(yīng)用的快捷登錄,在Android6.0谷歌才提供統(tǒng)一指紋SDK接口,在6.0之前都是各個廠商自定義。

2、使用

下面介紹如何在我們的應(yīng)用中加入指紋登錄的功能,之前實現(xiàn)指紋解鎖都是用的FingerprintManager類,F(xiàn)ingerprintManager在最新的Android 9.0系統(tǒng)上已經(jīng)被廢棄了,當(dāng)Google在v4包中把FingerprintManager改為了FingerprintManagerCompat,而Compat是兼容的意思,所以Google在v4包中做了一些兼容性處理,官方推薦使用后者。所以本demo用的就是FingerprintManagerCompat工具類。
一、申請權(quán)限

<!-- 指紋權(quán)限 -->
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>

二、驗證手機(jī)是否支持指紋,如果手機(jī)不支持,那就沒辦法了。

FingerprintManagerCompat提供了三個方法:

  • isHardwareDetected() 判斷是否有硬件支持
  • isKeyguardSecure() 判斷是否設(shè)置鎖屏,因為一個手機(jī)最少要有兩種登錄方式
  • hasEnrolledFingerprints() 判斷系統(tǒng)中是否添加至少一個指紋
/**
* 判斷是否支持指紋識別
*/
public static boolean supportFingerprint(Context mContext) {
    if (Build.VERSION.SDK_INT < 23) {
        Toast.makeText(mContext, "您的系統(tǒng)版本過低,不支持指紋功能", Toast.LENGTH_SHORT).show();
        return false;
    } else {
        KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
        FingerprintManagerCompat fingerprintManager = FingerprintManagerCompat.from(mContext);
        if (!fingerprintManager.isHardwareDetected()) {
            Toast.makeText(mContext, "您的系統(tǒng)版本過低,不支持指紋功能", Toast.LENGTH_SHORT).show();
            return false;
        } else if (keyguardManager != null && !keyguardManager.isKeyguardSecure()) {
            Toast.makeText(mContext, "您的手機(jī)不支持指紋功能", Toast.LENGTH_SHORT).show();
            return false;
        } else if (!fingerprintManager.hasEnrolledFingerprints()) {
            Toast.makeText(mContext, "您至少需要在系統(tǒng)設(shè)置中添加一個指紋", Toast.LENGTH_SHORT).show();
            return false;
        }
    }
    return true;
}

三、開啟指紋登錄,一般來說都是彈出個提示框用于顯示指紋識別的狀態(tài)。
首先,生成一個對稱加密的key

private static final String DEFAULT_KEY_NAME = "default_key";

@TargetApi(23)
private void initKey() {
    try {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                .setUserAuthenticationRequired(true)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
        keyGenerator.init(builder.build());
        keyGenerator.generateKey();
        initCipher(keyStore);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

然后,通過生成的key初始化生成一個Cipher對象

@TargetApi(23)
private void initCipher(KeyStore keyStore) {
    try {
        SecretKey key = (SecretKey) keyStore.getKey(DEFAULT_KEY_NAME, null);
        Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
                + KeyProperties.BLOCK_MODE_CBC + "/"
                + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        showFingerPrintDialog(cipher);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

最后,通過上面生成的Cipher去開啟指紋驗證

private void showFingerPrintDialog(Context context, Cipher cipher) {
    FingerprintManagerCompat fingerprintManagerCompat = FingerprintManagerCompat.from(context);
    FingerprintManagerCompat.CryptoObject cryptoObject = new FingerprintManagerCompat.CryptoObject(cipher);
    CancellationSignal mCancellationSignal = new CancellationSignal();
    //識別過程中可以手動取消指紋識別
    //mCancellationSignal.cancel();
    fingerprintManagerCompat.authenticate(cryptoObject, 0, mCancellationSignal, new MyCallBack(), null);
}

下面詳細(xì)說一下,剛才開啟指紋驗證的時候的步驟:
1、創(chuàng)建一個FingerprintManagerCompat對象,上面有說到谷歌已經(jīng)不推薦使用FingerprintManager類。

FingerprintManagerCompat fingerprintManagerCompat = FingerprintManagerCompat.from(context);

2、拿到FingerprintManagerCompat對象后就可以調(diào)authenticate方法進(jìn)行指紋識別了,這里面需要傳遞幾個參數(shù):
(1)CryptoObject 這是一個加密類的對象,指紋掃描器會使用這個對象來判斷認(rèn)證結(jié)果的合法性。這個對象可以是null,但是這樣的話,就意味這app無條件信任認(rèn)證的結(jié)果,雖然從理論上這個過程可能被攻擊,數(shù)據(jù)可以被篡改,這是app在這種情況下必須承擔(dān)的風(fēng)險。因此,建議這個參數(shù)不要置為null。這里就需要使用之前初始化的Cipher去創(chuàng)建一個CryptoObject 對象。

FingerprintManagerCompat.CryptoObject cryptoObject = new FingerprintManagerCompat.CryptoObject(cipher);

(2)flags 標(biāo)識位,這個標(biāo)志位應(yīng)該是保留將來使用的,在這里我們傳0就可以了。
(3)cancel這個是CancellationSignal類的一個對象,這個對象用來在指紋識別器掃描用戶指紋的是時候取消當(dāng)前的掃描操作,如果不取消的話,那么指紋掃描器會移植掃描直到超時(一般為30s,取決于具體的廠商實現(xiàn)),這樣的話就會比較耗電。建議這個參數(shù)不要置為null。識別過程中可以手動取消指紋識別。

CancellationSignal mCancellationSignal = new CancellationSignal();
//識別過程中可以手動取消指紋識別
//mCancellationSignal.cancel();

(4)callback這個參數(shù)很重要,看名字就知道這是個回調(diào)的接口,這個參數(shù)等最后我們詳細(xì)來介紹。這個參數(shù)不能為null。
(5)handler這是Handler類的對象,F(xiàn)ingerprintManagerCompat將會使用這個handler中的looper來處理來自指紋識別硬件的消息。一般來說,我們開發(fā)的時候可以直接傳null,因為FingerprintManagerCompat會默認(rèn)使用app的main looper來處理。
3、最后我們來說一下剛才的callback這個參數(shù)

public class MyCallBack extends FingerprintManagerCompat.AuthenticationCallback {

   @Override
   public void onAuthenticationError(int errMsgId, CharSequence errString) {
       //當(dāng)出現(xiàn)錯誤的時候回調(diào)此函數(shù),比如多次嘗試都失敗了的時候,errString是錯誤信息
       //一般來說我們都是先判斷一下是不是自己手動取消
       Log.e("TAG", "errMsgId=" + errMsgId);
       if (errMsgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT) {
           Log.e("TAG", "" + errString);
       }
   }

   //當(dāng)指紋驗證失敗的時候會回調(diào)此函數(shù),失敗之后允許多次嘗試,失敗次數(shù)過多會停止響應(yīng)一段時間然后再停止sensor的工作
   @Override
   public void onAuthenticationFailed() {
       //指紋認(rèn)證失敗,請再試一次
       Log.e("TAG", "onAuthenticationFailed");
   }

   @Override
   public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
      //錯誤時提示幫助,比如說指紋錯誤,我們將顯示在界面上 讓用戶知道情況
      Log.e("TAG", "helpString=" + helpString);
   }

   //當(dāng)驗證的指紋成功時會回調(diào)此函數(shù),然后不再監(jiān)聽指紋sensor
   @Override
   public void onAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result) {
       //這里我們可以做取消彈框之類的
       Log.e("TAG", "onAuthenticationSucceeded=" + result.toString());
   }
}

四、總結(jié)
以上就是一個開發(fā)指紋識別的基本過程,希望對大家有所幫助。。。

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

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

  • 好久沒寫文章了,最近也比較偷懶,今天繼續(xù)討論我實際開發(fā)中遇到的需求,那就是關(guān)于APP解鎖,大家都知道?,F(xiàn)在越來越多...
    青蛙要fly閱讀 3,266評論 2 26
  • 最近在做指紋登錄,然后網(wǎng)上一大堆,but,幾乎都只是說指紋識別,識別后如何登錄幾乎沒有資料。 其他基礎(chǔ)的就不說了,...
    Stefan_Lau閱讀 1,019評論 0 1
  • 一、簡述 業(yè)務(wù)需求,需要指紋登錄,鑒于市面上的資料不是特別齊全,走了不少彎路?,F(xiàn)在通了,寫點東西給大伙做個參考。末...
    Edgar_Ng閱讀 11,533評論 8 14
  • 參考文章 首先是安卓提供的接口,所有關(guān)于指紋識別的接口全部在handroid.hardware.fingerpri...
    lambentlight閱讀 2,464評論 0 0
  • 簡介 隨著互聯(lián)網(wǎng)的發(fā)展不光手機(jī)配置越來越高,app產(chǎn)品要求也越來越高了?,F(xiàn)在做APP時產(chǎn)品都會讓我們加上 多語言、...
    艾曼大山閱讀 6,476評論 6 85

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