将 reCAPTCHA Enterprise 与 Android 应用集成

本页介绍如何在您的 Android 应用中集成 reCAPTCHA Enterprise。

如果要为可疑流量提供视觉验证,您可以使用 SafetyNet reCAPTCHA API

准备工作

  1. 为 reCAPTCHA Enterprise 准备好环境

  2. 为 Android 应用平台创建 reCAPTCHA 密钥

    或者,您可以通过执行以下任一步骤来复制适用于 Android 的现有 reCAPTCHA 密钥的 ID:

    • 如需从 Google Cloud 控制台复制现有密钥的 ID,请执行以下操作:

      1. 转到 reCAPTCHA Enterprise 页面。

        转到 reCAPTCHA Enterprise

      2. 在 reCAPTCHA 密钥列表中,将指针悬停在要复制的密钥上,然后点击
    • 如需使用 REST API 复制现有密钥的 ID,请使用 projects.keys.list 方法。
    • 如需使用 gcloud CLI 复制现有密钥的 ID,请使用 gcloud recaptcha keys list 命令。

准备 Android 环境

原生 Android

  1. 下载并安装最新版本的 Android Studio,以准备开发环境。

  2. 确保您的应用的最低 Android SDK 值设置为 API 19:Android 4.4 (KitKat)。您可以将应用的最低 SDK 设置为 API 19,也可以创建新的移动应用。

  3. 如果您要创建新的移动应用,请通过启动新的 Android Studio 项目来创建测试应用:

    1. 选择 Empty Activity。如果您要在应用中使用 Jetpack Compose,请选择 Empty Compose Activity
    2. 将语言设置为 kotlin
    3. 将最低 SDK 值设置为 API 19: Android 4.4 (KitKat)
  4. 确保 Google 的 Maven 制品库 google() 位于项目级 build.gradle 文件的仓库列表中,如以下代码段所示:

    allprojects {
        repositories {
            google()
        }
    }
    

    有关详情,请参阅 Google 的 Maven 制品库

  5. 如需添加 reCAPTCHA Enterprise API 依赖项,请将以下构建规则添加到应用级层 build.gradle 文件的 dependencies 部分。

      implementation 'com.google.android.recaptcha:recaptcha:18.4.0'
    

    如需详细了解如何在 Android 应用中添加依赖项,请参阅添加 build 依赖项

  6. 在应用清单中的第一个 <manifest> 标记与第一个 <application> 标记(例如 AndroidManifest.xml)之间添加互联网权限。必须具备此权限,因为 reCAPTCHA Enterprise API 涉及网络操作。

    <manifest ...>
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application ...>
        ...
      </application>
    </manifest>
    
  7. 如果您想在新项目中使用 AndroidX 库,请将 SDK 编译为 Android 9.0 或更高版本,并将以下代码段添加到 gradle.properties

    android.useAndroidX=true
    android.enableJetifier=true
    

    如需了解详情,请参阅迁移到 AndroidX

Flutter

如需详细了解如何通过 Flutter 使用 reCAPTCHA Enterprise,请参阅 Flutter 文档

ReactNative

如需详细了解如何通过 React Native 使用 reCAPTCHA Enterprise,请参阅 React Native 文档

将 reCAPTCHA Enterprise 与 Android 应用集成

  1. 使用您为 Android 应用创建的 reCAPTCHA 密钥 (KEY_ID) 来实例化客户端。

    Kotlin

    class MainActivity : AppCompatActivity() {
    
        private lateinit var recaptchaClient: RecaptchaClient
    
        override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
          initializeRecaptchaClient()
          // ... rest of onCreate code
        }
    
        private fun initializeRecaptchaClient() {
          lifecycleScope.launch {
            Recaptcha.getClient(application, "KEY_ID")
              .onSuccess { client ->
                recaptchaClient = client
              }
              .onFailure { exception ->
                // Handle communication errors ...
                // See "Handle communication errors" section
              }
          }
        }
    
        // ... rest of activity code.
    }
    

    Java

    public final class MainActivity extends Activity {
      @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initializeRecaptchaClient();
        // ... rest of onCreate code
      }
    
      private void initializeRecaptchaClient() {
        Recaptcha
          .getTasksClient(getApplication(), "KEY_ID")
          .addOnSuccessListener(
              this,
              new OnSuccessListener<RecaptchaTasksClient>() {
                @Override
                public void onSuccess(RecaptchaTasksClient client) {
                  MainActivity.this.recaptchaTasksClient = client;
                }
              })
          .addOnFailureListener(
              this,
              new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                  // Handle communication errors ...
                  // See "Handle communication errors" section
                }
              });
      }
    
      // ... rest of activity code.
    }
    
  2. 对于使用 reCAPTCHA Enterprise 保护的应用中的每项操作,请调用 execute 方法并传递 RecaptchaAction。reCAPTCHA Enterprise 提供了一组内置操作;如有必要,您可以创建自定义操作。

    以下代码段展示了如何使用 execute 保护 LOGIN 操作。

    Kotlin

    private fun executeLoginAction() {
      lifecycleScope.launch {
        recaptchaClient
          .execute(RecaptchaAction.LOGIN)
          .onSuccess { token ->
            // Handle success ...
            // See "What's next" section for instructions
            // about handling tokens.
          }
          .onFailure { exception ->
            // Handle communication errors ...
            // See "Handle communication errors" section
          }
      }
    }
    

    Java

    private void executeLoginAction(View v) {
      assert recaptchaTasksClient != null;
      recaptchaTasksClient
        .executeTask(RecaptchaAction.LOGIN)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<String>() {
              @Override
              public void onSuccess(String token) {
                // Handle success ...
                // See "What's next" section for instructions
                // about handling tokens.
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle communication errors ...
                // See "Handle communication errors" section
              }
            });
    }
    

以下示例代码段展示了在单个 Activity 应用中完全集成 getClient()execute() 方法的过程:

Kotlin

class MainActivity : AppCompatActivity() {

  private lateinit var recaptchaClient: RecaptchaClient

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    initializeRecaptchaClient()
    findViewById<View>(R.id.btn_login).setOnClickListener { executeLoginAction() }
    findViewById<View>(R.id.btn_redeem).setOnClickListener { executeRedeemAction() }
  }

  private fun initializeRecaptchaClient() {
    lifecycleScope.launch {
      Recaptcha.getClient(application, "KEY_ID")
        .onSuccess { client ->
          recaptchaClient = client
        }
        .onFailure { exception ->
          // Handle communication errors ...
          // See "Handle communication errors" section
        }
    }
  }

  private fun executeLoginAction() {
    lifecycleScope.launch {
      recaptchaClient
        .execute(RecaptchaAction.LOGIN)
        .onSuccess { token ->
          // Handle success ...
          // See "What's next" section for instructions
          // about handling tokens.
        }
        .onFailure { exception ->
          // Handle communication errors ...
          // See "Handle communication errors" section
        }
    }
  }

  private fun executeRedeemAction(){
    lifecycleScope.launch {
      recaptchaClient
        .execute(RecaptchaAction.custom("redeem"))
        .onSuccess { token ->
          // Handle success ...
          // See "What's next" section for instructions
          // about handling tokens.
        }
        .onFailure { exception ->
          // Handle communication errors ...
          // See "Handle communication errors" section
        }
    }
  }
}

Java

public final class MainActivity extends Activity {
  @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initializeRecaptchaClient();
    findViewById(R.id.btn_login).setOnClickListener(this::executeLoginAction);
    findViewById(R.id.btn_redeem).setOnClickListener(this::executeRedeemAction);
  }

  private void initializeRecaptchaClient() {
    Recaptcha
      .getTasksClient(getApplication(), "KEY_ID")
      .addOnSuccessListener(
          this,
          new OnSuccessListener<RecaptchaTasksClient>() {
            @Override
            public void onSuccess(RecaptchaTasksClient client) {
              MainActivity.this.recaptchaTasksClient = client;
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
          });
  }

  private void executeLoginAction(View v) {
    assert recaptchaTasksClient != null;
    recaptchaTasksClient
      .executeTask(RecaptchaAction.LOGIN)
      .addOnSuccessListener(
          this,
          new OnSuccessListener<String>() {
            @Override
            public void onSuccess(String token) {
              // Handle success ...
              // See "What's next" section for instructions
              // about handling tokens.
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
          });
  }

  private void executeRedeemAction(View v) {
    assert recaptchaTasksClient != null;
    recaptchaTasksClient
      .executeTask(RecaptchaAction.custom("redeem"))
      .addOnSuccessListener(
          this,
          new OnSuccessListener<String>() {
            @Override
            public void onSuccess(String token) {
              // Handle success ...
              // See "What's next" section for instructions
              // about handling tokens.
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
          });
  }
}

为 API 调用设置超时

您可以使用每个 API 的 timeout 属性来为 getClientexecute API 指定超时值。

getClient 的默认超时时间为 10 秒,execute API 的默认超时时间为 10 秒。

Kotlin

  • 调用 getClient 时设置超时。

        lifecycleScope.launch {
          Recaptcha.getClient(application, "KEY_ID", timeout = 20000L)
            .onSuccess { client ->
              recaptchaClient = client
            }
            .onFailure { exception ->
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
        }
    

    此代码段将 getClient 的超时设置为 20 秒。

  • 调用 execute 时设置超时。

        lifecycleScope.launch {
          recaptchaClient
            .execute(RecaptchaAction.LOGIN(), timeout = 10000L)
            .onSuccess { token ->
              // Handle success ...
              // See "What's next" section for instructions
              // about handling tokens.
            }
            .onFailure { exception ->
              // Handle communication errors ...
              // See "Handle communication errors" section
            }
        }
    

    此代码段将 execute 的超时设置为 10 秒。

Java

  • 调用 getClient 时设置超时。

      Recaptcha
        .getTasksClient(getApplication(), "KEY_ID", 20000L)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<RecaptchaTasksClient>() {
              @Override
              public void onSuccess(RecaptchaTasksClient client) {
                MainActivity.this.recaptchaTasksClient = client;
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle communication errors ...
                // See "Handle communication errors" section
              }
            });
    

    此代码段将 getClient 的超时设置为 20 秒。

  • 调用 execute 时设置超时。

      recaptchaTasksClient
        .executeTask(RecaptchaAction.custom("redeem"), 10000L)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<String>() {
              @Override
              public void onSuccess(String token) {
                // Handle success ...
                // See "What's next" section for instructions
                // about handling tokens.
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Handle communication errors ...
                // See "Handle communication errors" section
              }
            });
    

    此代码段将 execute 的超时设置为 10 秒。

处理通信错误

如果您的应用无法成功与 reCAPTCHA 服务通信,则可能是因为 API 遇到了错误。您必须在应用中添加逻辑,以妥善处理此类错误。

如需详细了解常见 API 错误的缓解措施,请参阅 RecaptchaErrorCode

API 参考文档

如需查看 reCAPTCHA API for Android 的完整参考,请参阅 com.google.android.recaptcha

后续步骤

  • 如需评估 reCAPTCHA 响应令牌,请创建评估