8

众所周知,从 android 9.0 开始,android 引入了BiometricPrompt Api来为越来越多的生物识别传感器(例如指纹、Face ID 等)提供标准的身份验证体验。

现在有了这个新的 BiometricPrompt Api,用户可以通过指纹、面部扫描仪或虹膜扫描(取决于他们的生物识别偏好)进行身份验证。BiometricPrompt api 会处理这个问题,它会通过各种回调通知我们。

下面是我显示生物识别提示的代码。

 biometricPrompt = new BiometricPrompt.Builder(context)
            .setTitle("FingerPrint Authentication")
            .setSubtitle("Login via Fingerprint")
            .setDescription("Touch Fingerprint Sensor")
            .setNegativeButton("Cancel", context.getMainExecutor(),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            Log.d(TAG,"Cancelled");
                        }
                    })
            .build();

现在,如果您看到我的代码,我将 title 设置为Fingerprint Authentication。现在在设备设置中,如果用户将生物特征偏好设置为人脸 ID而不是指纹,那么这个biometricPrompt将通过人脸 ID 对用户进行身份验证,即使用户一直触摸传感器,指纹传感器也不会工作。这会造成混乱,因为生物特征标题说的是“指纹认证”,而用户实际上是通过faceID进行认证的

有什么方法可以让我们知道用户选择了哪些生物特征偏好(例如指纹或 FaceID)?因此,基于该偏好,我可以在 BiometricPrompt 上显示适当的消息,这样用户就不会感到困惑。

我已经探索了 BiometricPrompt 中的所有 api,但可以找到与 BiometricPreference 相关的任何内容。

任何帮助将不胜感激。

4

4 回答 4

4

虽然不是一个完美的解决方案,但您可以使用 PackageManager API 来确定设备是否具有验证器硬件,例如:

if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE))
{
}

我创建了一个辅助类,如下所示:

class BiometricAuthenticator
{
 public enum BiometricType
 {
  FINGERPRINT,
  FACE, 
  IRIS,
  NONE
 }

 public static boolean hasBiometricAuthenticator(Context context)
 {
    int biometry = BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED;
    if (VERSION.SDK_INT >= 30)
        biometry = BiometricManager.from(context).canAuthenticate(Authenticators.BIOMETRIC_STRONG | Authenticators.BIOMETRIC_WEAK);
    else
        biometry = BiometricManager.from(context).canAuthenticate();

    switch (biometry)
    {
        case BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE:
        case BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED:
        case BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE:
             return (false);
        case BiometricManager.BIOMETRIC_SUCCESS:
             return true;
    }
    return (false);
 }

 /**
  * biometricType()
  *
  * returns type of biometry supported
  */
 public static BiometricType biometricType(Context context)
 {
    if (VERSION.SDK_INT < 23)
        return BiometricType.NONE;

    PackageManager packageManager = context.getPackageManager();

    // SDK 29 adds FACE and IRIS authentication
    if (VERSION.SDK_INT >= 29)
    {
        if (packageManager.hasSystemFeature(PackageManager.FEATURE_FACE))
            return BiometricType.FACE;
        if (packageManager.hasSystemFeature(PackageManager.FEATURE_IRIS))
            return BiometricType.IRIS;
        if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
            return BiometricType.FINGERPRINT;
        return BiometricType.NONE;
    }

    // SDK 23-28 offer FINGERPRINT only
    return (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) ? BiometricType.FINGERPRINT : BiometricType.NONE);
 }
}

这允许您确定是否存在生物特征验证器 ( hasBiometricAuthenticator),如果存在,则将验证器的类型作为BiometricType枚举返回。

一个设备理论上可以有多个身份验证器,并且biometricType()会在 API30+ 设备上按照优先顺序返回 FACE、IRIS,然后是 FINGERPRINT。

希望 Google 将来会公开更好的 API,但这些技巧至少会帮助在对话框中获得适当的提示

于 2020-11-24T17:25:20.143 回答
1

目前没有办法知道这类信息,去年已经打开了一个问题来询问它(https://issuetracker.google.com/issues/111315641)。由于 Android 试图简化开发人员在其应用程序中实现身份验证的路径,因此 BiometricPrompt 实现中缺少选项(请参阅 Android 文档以了解 BiometricPrompt 实现)。

于 2019-06-18T11:52:30.837 回答
0

在您的情况下,您可以简单地将您的标题字符串更改为“生物特征验证”,其他字符串也是如此。例如,请参阅下面指向的博客文章。

您的代码可能如下所示。但我也建议您使用strings.xml资源文件,而不是在代码中硬编码字符串。例如,将来您可能需要翻译服务。

biometricPrompt = new BiometricPrompt.Builder(context)
        .setTitle("Biometric Authentication")
        .setSubtitle("Login via biometrics")
        .setDescription("Use the Biometrics Sensor")
        .setNegativeButton("Cancel", context.getMainExecutor(),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Log.d(TAG,"Cancelled");
                    }
                })
        .build();

更广泛地说,必须在 API 团队决定开发人员是否应该知道用户的生物特征偏好之前评估隐私影响。目前还不清楚为什么开发人员需要这些信息。已经发布了两篇博客文章,涉及生物识别技术以及如何实施它们(博客一博客二)。除了这种区别(即强与弱)之外,用户喜欢或最终使用的外形因素似乎并不相关。

于 2020-01-13T17:35:43.730 回答
-1

在 Android R 中添加了一个名为setAllowedAuthenticators的方法

public BiometricPrompt.Builder setAllowedAuthenticators (int authenticators)

可选:指定可以由 BiometricPrompt 调用以对用户进行身份验证的身份验证器的类型。可用的身份验证器类型在 Authenticators 中定义,并且可以通过按位 OR 组合。默认为:

  • Authenticators#BIOMETRIC_WEAK 用于非加密身份验证,或
  • Authenticators#BIOMETRIC_STRONG 用于基于加密的身份验证。

如果使用此方法并且在调用 BiometricPrompt#authenticate(...) 时没有任何指定类型的身份验证器可用,则将取消身份验证并调用 AuthenticationCallback#onAuthenticationError(int, CharSequence) 并出现适当的错误代码。


此方法应优先于setDeviceCredentialAllowed(boolean)并在两者都使用时覆盖后者。使用此方法启用设备凭据身份验证(使用 Authenticators#DEVICE_CREDENTIAL)将替换提示上的否定按钮,导致同时调用 setNegativeButton(java.lang.CharSequence, java.util.concurrent.Executor, android.content. DialogInterface.OnClickListener)。


验证器

一个位字段,表示可能由提示调用的所有有效身份验证器类型。值为 0 或 BiometricManager.Authenticators.BIOMETRIC_STRONG、BiometricManager.Authenticators.BIOMETRIC_WEAK 和 BiometricManager.Authenticators.DEVICE_CREDENTIAL 的组合

于 2020-04-28T15:27:11.823 回答