# 如何使用生物识别进行认证（指纹 / Face ID）

> 检查可用性，并使用指纹、Face ID 或 Windows Hello 对用户进行认证。

Source: https://crossfly.dev/zh/docs/cookbook/device/biometria — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 如何使用生物识别进行认证（指纹 / Face ID）

**目的。** 通过请求 **生物识别认证**（指纹、Face ID/Touch
ID，或桌面端的 Windows Hello）来保护一个敏感操作。结果以异步方式通过回调返回。

## 使用的 API
- `boolean Biometry.isAvailable()` — 若设备至少有一种可用的生物识别方法则返回 `true`。**认证前务必先调用它**。
- `void Biometry.authenticate(String reason, String cancel, boolean onlyBiometric, Biometry.Callback callback)` — 显示原生的生物识别 UI。
  - `reason` — 说明为何需要认证的文本。
  - `cancel` — 取消按钮的标签。
  - `onlyBiometric` — `true` = 仅生物识别（不回退到 PIN/密码）；`false` = 允许 PIN/密码。
- `Biometry.Callback.onResult(AuthResult result, String message)` — 异步结果。
- `Biometry.AuthResult`（枚举）— `SUCCESS`、`FAILURE`、`CANCELLED`、`ERROR`。

> **注意。** 回调到达时 **不在 paint 线程上** —— 请将任何 UI 更新包裹在
> `Component.onUI(...)` 中。支持情况：Android（BiometricPrompt）、iOS（Face ID/Touch ID）、桌面端有限
> （Windows Hello）。生物识别数据永远不会离开设备 —— 只返回结果。

## 完整示例（复制、粘贴并运行）

```java
package com.exemplo;

import dev.crossfly.ui.*;                   // Window, Component, Button, Label
import dev.crossfly.ui.layout.*;            // VerticalLayout
import dev.crossfly.device.*;               // Biometry, Biometry.AuthResult

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Label resultado = new Label("");
      add(LAY_AUTO, resultado);

      Button acao = new Button("Autenticar");
      acao.onAction(c ->
      {
         if (Biometry.isAvailable())
         {
            Biometry.authenticate(
               "Autentique-se para acessar sua conta",  // reason
               "Cancelar",                               // cancel
               false,                                    // onlyBiometric=false → 允许 PIN/密码
               (result, message) -> Component.onUI(() ->   // 回调在 paint thread 之外
               {
                  switch (result)
                  {
                     case SUCCESS:   resultado.setText("Acesso liberado");        break;
                     case FAILURE:   resultado.setText("Falhou: " + message);     break;
                     case CANCELLED: resultado.setText("Cancelado");              break;
                     case ERROR:     resultado.setText("Erro: " + message);       break;
                  }
               }));
         }
         else
         {
            resultado.setText("Sem biometria disponível");   // 回退到应用的密码/PIN
         }
      });
      add(LAY_AUTO, acao);
   }
}
```

> 下面的片段只展示 **核心部分**。要运行它，请把它放进上面的 `MainWindow` 骨架里。

## 最小片段

```java
// 已在源码验证：Biometry.java (isAvailable, authenticate, Callback.onResult, AuthResult)
import dev.crossfly.device.*;              // Biometry, Biometry.AuthResult
import dev.crossfly.ui.*;                  // Component (onUI)

if (Biometry.isAvailable()) {
   Biometry.authenticate(
      "Autentique-se para acessar sua conta",  // reason
      "Cancelar",                               // cancel
      false,                                    // onlyBiometric=false → 允许 PIN/密码
      (result, message) -> Component.onUI(() -> {   // 回调在 paint thread 之外
         switch (result) {
            case SUCCESS:   liberarAcesso();                     break;
            case FAILURE:   mostrarErro("Falhou: " + message);   break;
            case CANCELLED: /* 用户取消了 */               break;
            case ERROR:     mostrarErro("Erro: " + message);     break;
         }
      }));
} else {
   // 无生物识别：回退到应用的密码/PIN
}
```

## 深入了解
- 生物识别指南：[生物识别](/docs/data-and-services/device-biometry)
