# Class Biometrics

java.lang.Object
com.codename1.security.Biometrics

public class Biometrics extends Object

Entry point for biometric authentication (Touch ID, Face ID, fingerprint, Android `BiometricPrompt`). Obtain the platform implementation via `getInstance()`; the returned subclass is owned by the active port.

A typical unlock flow:

    Biometrics b = Biometrics.getInstance();
    if (!b.canAuthenticate()) {
        // Fall back to password
        return;
    }
    b.authenticate("Unlock your account").onResult((success, err) -> {
        if (err != null) {
            BiometricError code = ((BiometricException) err).getError();
            // branch on code
        } else {
            // success
        }
    });

`authenticate(AuthenticationOptions)` returns an `AsyncResource` whose failure path completes with a `BiometricException` so callers can branch on the typed `BiometricError`.

##### Platform support

- iOS -- uses `LocalAuthentication.framework` (`LAContext`). Touch ID and Face ID on supported devices. Add the `ios.NSFaceIDUsageDescription` build hint when targeting Face ID hardware.
- Android -- uses `BiometricPrompt` on API 29+ (Android 10) and `FingerprintManagerCompat` on API 23-28. Fingerprint, face, and iris modalities are reported per `PackageManager` features. The legacy path goes through the support library rather than `android.hardware.fingerprint` directly, which Android removed in API 37, so an app compiled against any platform still authenticates on an API 23-28 device.
- JavaSE simulator -- behaves as a real device with no enrolled biometrics by default. The `Simulate -> Biometric Simulation` submenu in the simulator lets you toggle hardware availability, enrolled modalities, and the outcome of the next `authenticate(String)` call.
- All other platforms (desktop deploy, JavaScript, ...) -- this base class is returned as-is and acts as a non-supporting fallback: `isSupported()` / `canAuthenticate()` return `false` and `authenticate(String)` completes with `BiometricError.NOT_AVAILABLE`. Application code does not need platform `if` statements -- always gate biometrics on `canAuthenticate()` before invoking the prompt.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `Biometrics()`
  Subclasses are constructed by the port.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `AsyncResource<Boolean>`
  `authenticate(AuthenticationOptions opts)`
  Prompts the user to authenticate.
  `AsyncResource<Boolean>`
  `authenticate(String reason)`
  Convenience for `authenticate(new AuthenticationOptions().setReason(reason))`.
  `boolean`
  `canAuthenticate()`
  Returns `true` when the device is ready to authenticate right now: hardware present, at least one biometric enrolled, and not in a locked-out state.
  `List<BiometricType>`
  `getAvailableBiometrics()`
  Lists the biometric modalities currently enrolled.
  `static Biometrics`
  `getInstance()`
  Returns the platform-specific singleton owned by the current port.
  `boolean`
  `isSupported()`
  Returns `true` when biometric hardware exists on the device, regardless of whether the user has enrolled biometrics.
  `boolean`
  `stopAuthentication()`
  Cancels an in-flight `authenticate(AuthenticationOptions)` call if one is running.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### Biometrics

    protected Biometrics()
    Subclasses are constructed by the port. Application code obtains the active instance via `getInstance()`.

- ## Method Details

  - ### getInstance

    public static Biometrics getInstance()
    Returns the platform-specific singleton owned by the current port. On ports that do not implement biometrics this returns a base `Biometrics` instance whose methods report the device as unsupported, so calling code never needs a `null` check or a platform-specific `if`.

  - ### isSupported

    public boolean isSupported()
    Returns `true` when biometric hardware exists on the device, regardless of whether the user has enrolled biometrics. Combine with `canAuthenticate()` to gate UI affordances: show the "Use biometrics" toggle when `isSupported()` is true, but only invoke `authenticate(AuthenticationOptions)` when `canAuthenticate()` is also true. Returns `false` on the fallback base class.

  - ### canAuthenticate

    public boolean canAuthenticate()
    Returns `true` when the device is ready to authenticate right now: hardware present, at least one biometric enrolled, and not in a locked-out state. Returns `false` on the fallback base class.

  - ### getAvailableBiometrics

    public List<BiometricType> getAvailableBiometrics()

    Lists the biometric modalities currently enrolled. On iOS this is `BiometricType.FINGERPRINT` or `BiometricType.FACE`; on Android the list may contain `BiometricType.IRIS` as well, and Android API 30+ adds `BiometricType.STRONG` / `BiometricType.WEAK` authenticator class tags.

    ###### Returns

    an empty list when nothing is enrolled or the device is unsupported

  - ### authenticate

    public AsyncResource<Boolean> authenticate(AuthenticationOptions opts)

    Prompts the user to authenticate. The returned `AsyncResource` completes with `true` on success, or with a `BiometricException` on failure (consult `BiometricException.getError()` for the typed code). On the fallback base class this completes immediately with `BiometricError.NOT_AVAILABLE` so callers don't need to platform- check before invoking.

    ###### Parameters

    - `opts`: non-null configuration; `AuthenticationOptions.setReason(String)` should be set

  - ### authenticate

    public AsyncResource<Boolean> authenticate(String reason)
    Convenience for `authenticate(new AuthenticationOptions().setReason(reason))`.

  - ### stopAuthentication

    public boolean stopAuthentication()

    Cancels an in-flight `authenticate(AuthenticationOptions)` call if one is running. The pending `AsyncResource` completes with `BiometricError.USER_CANCELED`.

    ###### Returns

    `true` when a call was cancelled; `false` when no authentication was pending. Always `false` on the fallback base class.