响应身份验证回调

指纹扫描器以后台方式在自己的线程中运行,完成运行后,它将从 UI 线程调用 FingerprintManager.AuthenticationCallback 的方法之一,以报告扫描结果。 Android 应用程序必须提供自己的处理程序,来扩展此抽象类,并实现以下所有方法:

  • OnAuthenticationError(int errorCode, ICharSequence errString) - 存在不可恢复的错误时调用。 应用程序或用户只能通过尽可能地重试来修正此情况。
  • OnAuthenticationFailed() - 在检测到指纹但设备无法识别它时调用此方法。
  • OnAuthenticationHelp(int helpMsgId, ICharSequence helpString) - 在出现可恢复的错误时调用,例如扫描手指以快速扫过扫描程序。
  • OnAuthenticationSucceeded(FingerprintManagerCompati.AuthenticationResult result) - 在识别出指纹时调用。

若在调用 Authenticate 时使用了 CryptoObject,建议从 OnAuthenticationSuccessful 调用 Cipher.DoFinal。 密码被篡改或以错误方式初始化时,DoFinal 将引发异常,并指示指纹扫描器结果可能已从此应用程序外部被篡改。

注意

建议保持此回调类相对轻量级,并且无应用程序特定的逻辑。 回调应充当 Android 应用程序与指纹扫描器之间的“交警”。

身份验证回调处理程序示例

下面的类是最小 FingerprintManager.AuthenticationCallback 实现示例:

class MyAuthCallbackSample : FingerprintManagerCompat.AuthenticationCallback
{
    // Can be any byte array, keep unique to application.
    static readonly byte[] SECRET_BYTES = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // The TAG can be any string, this one is for demonstration.
    static readonly string TAG = "X:" + typeof (SimpleAuthCallbacks).Name;

    public MyAuthCallbackSample()
    {
    }

    public override void OnAuthenticationSucceeded(FingerprintManagerCompat.AuthenticationResult result)
    {
        if (result.CryptoObject.Cipher != null) 
        {
            try
            {
                // Calling DoFinal on the Cipher ensures that the encryption worked.
                byte[] doFinalResult = result.CryptoObject.Cipher.DoFinal(SECRET_BYTES);
    
                // No errors occurred, trust the results.              
            }
            catch (BadPaddingException bpe)
            {
                // Can't really trust the results.
                Log.Error(TAG, "Failed to encrypt the data with the generated key." + bpe);
            }
            catch (IllegalBlockSizeException ibse)
            {
                // Can't really trust the results.
                Log.Error(TAG, "Failed to encrypt the data with the generated key." + ibse);
            }
        }
        else
        {
            // No cipher used, assume that everything went well and trust the results.
        }
    }

    public override void OnAuthenticationError(int errMsgId, ICharSequence errString)
    {
        // Report the error to the user. Note that if the user canceled the scan,
        // this method will be called and the errMsgId will be FingerprintState.ErrorCanceled.
    }

    public override void OnAuthenticationFailed()
    {
        // Tell the user that the fingerprint was not recognized.
    }

    public override void OnAuthenticationHelp(int helpMsgId, ICharSequence helpString)
    {
        // Notify the user that the scan failed and display the provided hint.
    }
}

OnAuthenticationSucceeded 查看调用 Authentication 时是否向 FingerprintManager 提供了 Cipher。 若已提供,则对密码调用 DoFinal 方法。 这会关闭 Cipher,将其还原到初始状态。 若密码出现了问题,DoFinal 将引发异常,并将验证操作视为已失败。

OnAuthenticationErrorOnAuthenticationHelp 回调分别会收到一个指示何种问题的整数。 下面的部分说明各个可能的帮助或错误代码。 这两个回调的作用相似 - 用于通知应用程序指纹验证已失败。 它们的区别在于严重性。 OnAuthenticationHelp 是用户可恢复的错误,例如扫指纹的速度过快;OnAuthenticationError 是更为严重的错误,例如指纹扫描器损坏。

请注意,通过 CancellationSignal.Cancel() 消息取消指纹扫描时,将调用 OnAuthenticationErrorerrMsgId 参数的值将为 5 (FingerprintState.ErrorCanceled)。 AuthenticationCallbacks 实现处理此情况的方式可能会不同于其他错误,具体取决于要求。

指纹扫描成功但它与已注册设备的任何指纹都不匹配时,将调用 OnAuthenticationFailed

帮助代码和错误消息 ID

可从 FingerprintManager 类的 Android SDK 文档查看错误代码和帮助代码的列表和说明。 Xamarin.Android 使用 Android.Hardware.Fingerprints.FingerprintState 枚举表示这些值:

  • AcquiredGood -(值 0)获得的图像完好。

  • AcquiredImagerDirty -(值 3)传感器上可能有或已检测到灰尘,导致指纹图像过于杂乱。 例如,出现多次 AcquiredInsufficient 或确实在传感器上检测到灰尘后(像素卡滞、刈痕等),返回此值是正常的。 返回此值时,用户应采取措施来清理传感器。

  • AcquiredInsufficient -(值 2)检测到的情况(如皮肤干燥)或传感器可能有灰尘(请参阅 AcquiredImagerDirty)导致指纹图像过于杂乱,难以处理。

  • AcquiredPartial -(值 1)仅检测到了部分指纹图像。 注册时,应通知用户需如何操作来解决此问题,例如“用力按压传感器”。

  • AcquiredTooFast -(值 5)动作过快导致指纹不完整。 多数情况下此问题适用于线阵传感器,但是如果在采集指纹期间手指移动,也可能会发生此问题。 应要求用户慢速移动手指(线阵传感器),或在传感器上停留较长时间。

  • AcquiredToSlow -(值 4)由于缺少动作,指纹图像不可读。 多数情况下此问题适用于要求轻扫动作的线阵传感器。

  • ErrorCanceled -(值 5)指纹传感器不可用导致操作取消。 例如,在切换用户、设备锁定或其他挂起的操作阻止或禁用此操作时,可能会发生此问题。

  • ErrorHwUnavailable -(值 1)硬件不可用。 请稍后重试。

  • ErrorLockout -(值 7)尝试次数过多导致 API 锁定,操作被取消。

  • ErrorNoSpace -(值 4)针对注册等操作返回的错误状态;剩余存储不足以完成操作,导致操作无法完成。

  • ErrorTimeout -(值 3)当前请求运行时间过长时,会返回此错误状态。 这旨在防止程序无限期等待指纹传感器。 此超时特定于平台和传感器,但通常是 30 秒左右。

  • ErrorUnableToProcess -(值 2)传感器无法处理当前图像时会返回此错误状态。