溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

一篇文章教你從入門到精通 Google 指紋驗證功能

發布時間:2020-08-08 20:05:50 來源:ITPUB博客 閱讀:203 作者:vivo互聯網技術 欄目:移動開發

本文首發于 vivo互聯網技術 微信公眾號 
鏈接: https://mp.weixin.qq.com/s/EHomjBy4Tvm8u962J6ZgsA
作者:Sun Daxiang

Google 從 Android 6.0開始,提供了開放的指紋識別相關 API,通過此篇文章可以幫助開發者接入指紋驗證的基礎功能,并且提供了系統應用基于指紋驗證的功能擴展,如指紋驗證登錄功能核心流程圖和關鍵代碼分析。

一、基礎篇

從Android 6.0開始,Android 系統支持指紋識別功能,指紋識別的API主要是FingerprintManager。

FingerprintManager提供的公共方法有,判斷系統是否支持指紋,系統是否錄入過指紋,發起指紋驗證,取消驗證,驗證結果回調。

隱藏方法有,獲取系統中指紋列表,獲取指紋id等信息。然而 Android 9.0以后 Google官方不推薦使用FingerprintManager 接口, 推薦使用

BiometricPrompt代替, 因為BiometricPrompt接口不能夠自定義彈框樣式,各業務線還未統一使用,下面會介紹此接口接入方法:

1、 效果演示和demo結構介紹

1.1 指紋驗證效果

  一篇文章教你從入門到精通 Google 指紋驗證功能

1.2 demo的代碼結構

一篇文章教你從入門到精通 Google 指紋驗證功能

1.3 核心類說明

因指紋功能有Android 6.0和 Android 9.0適配問題,所以使用FingerprintVersionM和FingerprintVersionP分別實現對不同 Android 版本的封裝實現。

FingerprintManagerWrapper, FIngerpintVersionM,FingerprintVersionP都實現IFingerprintInterface接口,統一通過startAuth() cancelAuth方法。

調起指紋驗證和取消指紋驗證

核心類說明:

一篇文章教你從入門到精通 Google 指紋驗證功能

核心類的關系圖:

一篇文章教你從入門到精通 Google 指紋驗證功能

2、接入流程

通過下面的6步接入后,可以正常使用指紋驗證功能,包括系統是否支持指紋,是否錄入過指紋,拉起指紋驗證,取消指紋驗證,指紋驗證結果回調,適配Android 6.0和Android 9.0。

第一步:在manifest文件中增加如下指紋權限功能 ,判斷方法見方法見實現代碼見 2.3章節

第六步:在activity生命周期onStop()調用取消驗證接口,關閉指紋驗證功能 見2.4章節

一篇文章教你從入門到精通 Google 指紋驗證功能

2.1 增加指紋使用權限

<!--android 9.0及以上系統使用指紋權限 -->
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<!--android 6.0至8.0及以上系統使用指紋權限 -->
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<!--android 6.0及以上,獲取指紋信息權限,系統應用提升篇中會使用到 -->
<uses-permission android:name="android.permission.MANAGE_FINGERPRINT"/>

2.2 調起指紋驗證

FingerprintVersionP和FingerprintVersionM分別兼容 Android 6.0和 Android9.0指紋驗證功能,FingerprintManagerWrapper,FingerprintVersionP,FingerprintVersionM統一實現IFingerprintInterface接口

public FingerprintManagerWrapper() {
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            mFingerprintImp = new FingerprintVersionP();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mFingerprintImp = new FingerprintVersionM();
        }
    }
}
/**
 * 先判斷系統是否支持指紋,系統是否錄入過指紋,再調用指紋認證統一方法
 */
public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
    Log.i(TAG, "------startFingerAuthenticate() enter --------");
    //判斷指紋設備當前是否可以使用
    if (!isHardwareDetected()) {
        Log.e(TAG, "------hardware detected!!!--------");
        return;
    }
  
    //判斷當前是否有指紋
    if (!hasEnrolledFingerprints()) {
        Log.e(TAG, "-----has no Fingerprints!!!--------");
        return;
    }
    mFingerprintImp.startAuth(listener);
}
  
  
/**
 * android6.0android9.0統一驗證和取消接口
 */
interface IFingerprintInterface {
    public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener);
  
    public void canceAuth();
}

FingerprintVersionM中實現 Android 6.0指紋驗證代碼如下:

public class FingerprintVersionM implements IFingerprintInterface {
  
  
  @Override
  public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
  
  
     //取消指紋驗證類
     CancellationSignal  mCancellationSignal = new CancellationSignal();
  
     MyAuthenticationCallback authenticationCallback = new MyAuthenticationCallback();
     /**
       * 參數說明:
       * CryptoObject - 如果需要的話可以添加加密對象CryptoObject
       * CancellationSignal - 用來取消指紋驗證,如果想手動取消驗證,調用該參數的cancel方法
       * int - 沒意義,默認傳0
       * AuthenticationCallback -  回調驗證的結果,成功、失敗等
       * Handler - 傳null則默認創建一個在主線程上的Handler來傳遞消息
       */
     mFingerprintManager.authenticate(null, mCancellationSignal, 0, authenticationCallback, null); //調用識別接口
     }
  
  
}

FingerprintVersionP中實現 Android 9.0指紋驗證代碼如下:

public class FingerprintVersionP implements IFingerprintInterface {
  
  
    @Override
    public void startAuth(FingerprintManagerWrapper.FingerVerifyResultListener listener) {
  
  
        //用來取消指紋驗證
        CancellationSignal mCancellationSignal = new CancellationSignal();
        //回調驗證的結果,成功、失敗等
        AuthenticationCallback mAuthenticationCallback = new BiometricPrompt.AuthenticationCallback(){}
        //開始驗證
        mBiometricPrompt.authenticate(mCancellationSignal, mContext.getMainExecutor(), mAuthenticationCallback);
    }
}

2.3 指紋驗證回調

// 指紋驗證失敗回調方法
onAuthenticationFailed()
//指紋驗證成功回調方法 ,  有系統權限可以通過AuthenticationResult 獲取指紋的信息,指紋名稱,指紋id等
onAuthenticationSucceeded(AuthenticationResult result)
//指紋驗證失敗回調,helpMsgId=1006,helpString=6 手指移除太快
onAuthenticationHelp(int helpMsgId, CharSequence helpString)
//指紋嘗試多次后,指紋主動關閉。errMsgId=5,errString=指紋操作已取消。
onAuthenticationError(int errMsgId, CharSequence errString)
// android9.0以下使用 android.hardware.fingerprint.FingerprintManager.AuthenticationCallback
//android 9.0以上使用  android.hardware.biometrics.BiometricPrompt.AuthenticationCallback
  
  
private class MyAuthenticationCallback extends AuthenticationCallback {
  
    @Override
    public void onAuthenticationFailed() {
         //指紋驗證失敗回調方法
    }
  
    @Override
    public void onAuthenticationSucceeded(AuthenticationResult result) {
        //指紋驗證成功回調方法 ,  有系統權限可以通過AuthenticationResult 獲取指紋的信息,指紋名稱,指紋id等
    }
  
    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
        //指紋驗證失敗回調,helpMsgId=1006,helpString=6 手指移除太快
    }
  
  
    @Override
    public void onAuthenticationError(int errMsgId, CharSequence errString) {
        //指紋嘗試多次后,指紋主動關閉。errMsgId=5,errString=指紋操作已取消。
    }
  
}

一篇文章教你從入門到精通 Google 指紋驗證功能

2.4 取消指紋驗證

在activity的onStop方法中取消指紋驗證功能

// 屏下指紋彈框home鍵或者被其他頁面全部覆蓋后,需要關閉,重新拉起
@Override
protected void onStop() {
    super.onStop();
    //上面調起指紋驗證方法中,傳入的CancellationSignal對象
    mCancellationSignal.cancel();
}

2.5 判斷當前系統是否支持指紋

FingerprintManager雖然在 Android 9.0以后不推薦使用,但是Google各系統版本都支持FingerprintManager,而且9.0及以上版本暫未提供判斷是否支持指紋功能的 API

/**
 * 判斷當前指紋功能是否可用
 *
 * @return
 */
public boolean isHardwareDetected() {
    boolean isHardwareSupport = false;
    try {
        if (mFingerprintManager != null) {
            isHardwareSupport = mFingerprintManager.isHardwareDetected();
        }
    } catch (Exception e) {
        Log.e(TAG, "isHardwareDetected err ", e);
    }
    Log.e(TAG, "isHardwareDetected(),  isHardwareSupport= " + isHardwareSupport);
    return isHardwareSupport;
}

2.6 判斷系統是否錄入過指紋

同上使用FingerprintManager判斷系統是否錄入過指紋

/**
 * 判斷是否錄入過指紋
 *
 * @return
 */
public boolean hasEnrolledFingerprints() {
    boolean hasEnrolledFinger = false;
    try {
        if (mFingerprintManager != null) {
            hasEnrolledFinger = mFingerprintManager.hasEnrolledFingerprints();
        }
    } catch (Exception e) {
        Log.e(TAG, "hasEnrolledFingerprints err ", e);
    }
    Log.e(TAG, "hasEnrolledFingerprints(),  hasEnrolledFinger= " + hasEnrolledFinger);
    return hasEnrolledFinger;
}

以上基礎篇介紹了 Google提供的公共 API , 基本滿足指紋驗證的功能。

下面介紹獲取指紋id和指紋列表方法,可以滿足其他業務需求,比如帳號登錄,支付等功能。

二、系統應用提升篇

1、獲取到指紋id

指紋驗證成功后,根據FingerprintManager.AuthenticationResult 對象可以通過反射方法獲取到指紋id(指紋id是隱藏屬性),需要添加權限 

android.permission.MANAGE_FINGERPRINT, Android 6.0和 Android9.0中Fingerprint對象有差異:

Android 6.0中Fingerprint中包含有指紋id的屬性mFingerprintId和public方法getFingerprintId

Android 9.0 中Fingerprint類繼承BiometricAuthenticator.Identifer,并且指紋id也放入此類中,屬性名為mBiometricId ,方法為getBiometricId

一篇文章教你從入門到精通 Google 指紋驗證功能

(Android 9.0 相關類依賴關系)

一篇文章教你從入門到精通 Google 指紋驗證功能

(Android6.0類圖依賴關系)

因此使用反射獲取Fingerprint對象和指紋id方法需要適配 Android 6.0和 Android 9.0,詳細方法如下:

Android 6.0中AuthenticationResult反射獲取Fingerprint對象,Fingerprint對象getFingerId獲取到指紋id

Android 9.0以上指紋信息放在Fingerprint的父類中,所以需要通過clzz.getSuperclass()獲取父類對象,在反射方法getBiometricId獲取指紋 id

private static int getFingerId(AuthenticationResult result) {
    int fingerId = -1;
    try {
        Field field = result.getClass().getDeclaredField("mFingerprint");
        field.setAccessible(true);
        Object fingerPrint = field.get(result);
  
        Class<?> clzz = Class.forName("android.hardware.fingerprint.Fingerprint");
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            Log.i(TAG, "-------ANDROID Q-------");
            Class<?> supClass = clzz.getSuperclass();
            Method getBiometricId = supClass.getDeclaredMethod("getBiometricId");
            fingerId = (int) getBiometricId.invoke(fingerPrint);
        } else {
            Log.i(TAG, "------- ANDROID M-P-------");
            Method getFingerId = clzz.getDeclaredMethod("getFingerId");
            fingerId = (int) getFingerId.invoke(fingerPrint);
        }
        Log.d(TAG, "fingerId=" + fingerId);
  
    } catch (Exception e) {
        Log.e(TAG, "", e);
    }
    return fingerId;
}

2、獲取系統中指紋列表

系統錄入指紋,可以通過反射方法獲取到指紋列表中,各指紋信息

一篇文章教你從入門到精通 Google 指紋驗證功能

通過反射后獲取指紋列表json字符串:

android6.0:[{"mDeviceId":0,"mFingerId":1147763748,"mGroupId":0,"mName":"指紋 1"},{"mDeviceId":0,"mFingerId":412764029,"mGroupId":0,"mName":"指紋 2"}]  
android9.0: [{"mGroupId":0,"mBiometricId":-714471355,"mDeviceId":517254275456,"mName":"指紋 1"},{"mGroupId":0,"mBiometricId":-803114291,"mDeviceId":517254275456,"mName":"指紋 2"}]

一篇文章教你從入門到精通 Google 指紋驗證功能

詳細的反射代碼如下:

1: 將反射獲取的指紋列表json字符串,使用gson轉為AccountFingerprint對象(兼容android6.0-android10.0)
   
 Gson gson = new Gson();
 Object object = getEnrolledFingerprints(mFingerprintManager);
 String fingerListString = gson.toJson(object)
 // android6.0-android9.0   [{"mDeviceId":0,"mFingerId":1147763748,"mGroupId":0,"mName":"指紋 1"},{"mDeviceId":0,"mFingerId":412764029,"mGroupId":0,"mName":"指紋 2"}]
// android10.0    [{"mGroupId":0,"mBiometricId":-714471355,"mDeviceId":517254275456,"mName":"指紋 1"},{"mGroupId":0,"mBiometricId":-803114291,"mDeviceId":517254275456,"mName":"指紋 2"}]
 List<AccountFingerprint> list = gson.fromJson(fingerListString, new TypeToken<List<AccountFingerprint>>() {}.getType());
  
  
2:反射FingerprintManager調用getEnrolledFingerprints方法獲取已錄入指紋列表
   
   
/**
 * 反射獲取當前用戶的所有指紋信息列表
 *
 * @param fm FingerprintManagerWrapper
 * @return 指紋信息列表
 */
public static Object getEnrolledFingerprints(FingerprintManager fm) {
    try {
        if (fm != null) {
            Object obj = invokeMethod(fm, "getEnrolledFingerprints");
         return obj;
         }
    } catch (Exception e) {
        VLog.e(TAG, "getEnrolledFingerprints()", e);
     }
   
    return null;
}
  
  
3: 自定義的AccountFingerprint bean,兼容android6-android10
   
   
//創建的指紋bean
public class AccountFingerprint {
   
    @SerializedName("mBiometricId")
    private int mBiometricId;
   
 @SerializedName("mFingerId")
    private int mFingerId;
   
 @SerializedName("mGroupId")
    private int mGroupId;
   
 @SerializedName("mDeviceId")
    private long mDeviceId;
   
 @SerializedName("mName")
    private String mPrintName;
}

3、指紋認證實用場景介紹(指紋登錄帳號功能)

舉個栗子:獲取指紋id和指紋列表后可以實現指紋登錄功能

  1. 首先獲取設備的指紋列表同步給服務器,服務器記錄帳號,設備,指紋列表,綁定關系
  2. 用戶使用指紋驗證的id + 帳號+設備發起登錄請求
  3. 服務器校驗當前帳號,指紋id,設備,是否有同步保存記錄,并返回驗證結果

指紋登錄效果

一篇文章教你從入門到精通 Google 指紋驗證功能

指紋登錄交互時序圖

一篇文章教你從入門到精通 Google 指紋驗證功能

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女