將 reCAPTCHA 整合至 Android 應用程式

本頁說明如何在 Android 應用程式中整合 reCAPTCHA。

SDK 會使用反射和動態程式碼,在現有已部署的應用程式/SDK 中修改及改善偵測系統。系統中可用的類別集會限制在受控清單中,避免干擾應用程式。

事前準備

  1. 準備 reCAPTCHA 環境

  2. 為 Android 應用程式平台建立 reCAPTCHA 金鑰

    或者,您也可以執行下列其中一個步驟,複製現有 Android 適用的 reCAPTCHA 金鑰 ID:

    • 如要從 Google Cloud 控制台複製現有金鑰的 ID,請按照下列步驟操作:

      1. 前往 reCAPTCHA 頁面。

        前往 reCAPTCHA

      2. 在 reCAPTCHA 金鑰清單中,將指標懸停在要複製的金鑰上,然後按一下
    • 如要使用 REST API 複製現有金鑰的 ID,請使用 projects.keys.list 方法。
    • 如要使用 gcloud CLI 複製現有金鑰的 ID,請使用 gcloud recaptcha keys list 指令。

準備 Android 環境

內建 Android

  1. 下載並安裝最新版 Android Studio,準備好開發環境。

  2. 確認應用程式的最低 Android SDK 值已設為「API 23:Android 6.0 (Marshmallow)」

  3. 如果您要建立新的行動應用程式,請啟動新的 Android Studio 專案,建立測試應用程式:

    1. 選取「Empty Activity」。如要在應用程式中使用 Jetpack Compose,請選擇「Empty Compose Activity」
    2. 將語言設為 kotlin
    3. 將最低 SDK 值設為「API 23: Android 6.0 (Marshmallow)」
  4. 確認 Google 的 Maven 存放區 google() 位於專案層級 build.gradle 檔案的存放區清單中,如下列程式碼片段所示:

    allprojects {
        repositories {
            google()
        }
    }
    

    詳情請參閱「Google 的 Maven 存放區」一文。

  5. 如要新增 reCAPTCHA API 依附元件,請在應用程式層級 build.gradle 檔案的 dependencies 區段中新增下列建構規則。

      implementation 'com.google.android.recaptcha:recaptcha:18.8.0-beta01'
    

    如要進一步瞭解如何在 Android 應用程式中新增依附元件,請參閱「新增建構依附元件」。

  6. 在應用程式資訊清單的第一個 <manifest> 標記和第一個 <application> 標記之間新增網際網路權限 (例如 AndroidManifest.xml)。由於 reCAPTCHA 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 的詳細操作說明,請參閱 Flutter 說明文件

React Native

如需透過 React Native 使用 reCAPTCHA 的詳細操作說明,請參閱 React Native 說明文件

將 reCAPTCHA 整合至 Android 應用程式

  1. 使用您為 Android 應用程式建立的 reCAPTCHA 金鑰 (KEY_ID),例項化用戶端。

    包含 fetchClient 的 Kotlin

    fetchClient 方法會立即傳回用戶端,並在背景初始化 SDK。如果發生網路連線失敗,系統會重試與 reCAPTCHA 伺服器的通訊。

    class CustomApplication : Application() {
    
        private lateinit var recaptchaClient: RecaptchaClient
        // we recommend initializing in a ViewModel
        private val recaptchaScope = CoroutineScope(Dispatchers.IO)
    
        override fun onCreate() {
          super.onCreate()
          initializeRecaptchaClient()
        }
    
        private fun initializeRecaptchaClient() {
          recaptchaScope.launch {
            try {
              recaptchaClient = Recaptcha.fetchClient(application, "KEY_ID")
            } catch(e: RecaptchaException) {
              // Handle errors ...
              // See "Handle errors" section
            }
          }
        }
    }
    

    Java 與 fetchClient

    public final class CustomApplication extends Application {
      @Nullable private RecaptchaTasksClient recaptchaTasksClient = null;
    
      @Override
      protected void onCreate() {
        super.onCreate();
        initializeRecaptchaClient();
      }
    
      private void initializeRecaptchaClient() {
        Recaptcha
          .fetchTaskClient(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 errors ...
                  // See "Handle errors" section
                }
              });
      }
    }
    

    SDK 初始化作業可能需要幾秒鐘才能完成。為減輕延遲問題,請盡可能提早初始化用戶端,例如在自訂 Application 類別的 onCreate() 呼叫期間。您不應讓 UI 元素封鎖 reCAPTCHA SDK。

  2. 針對應用程式中受 reCAPTCHA 保護的每個動作,請呼叫 execute 方法,並傳遞 RecaptchaAction。reCAPTCHA 提供內建的動作集,如有需要,您也可以建立自訂動作。

    下列程式碼片段說明如何使用 execute 保護 LOGIN 動作。

    Kotlin

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

    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 errors ...
              }
            });
    }
    

從 getClient 方法遷移至 fetchClient 方法

fetchClient 方法會傳回 RecaptchaClient,在網路連線失敗時重試初始化作業。如果建立用戶端時應用程式沒有網路存取權,用戶端會持續重試,並在取得網路時成功初始化。

如果您呼叫 execute(timeout),但用戶端尚未準備就緒,系統會先嘗試初始化,再傳回權杖或 RecaptchaErrorCode

以下範例說明如何從 getClient 遷移至 fetchClient

Kotlin

// Migrate from getClient
private fun initializeWithGetClient() {
  recaptchaScope.launch {
    Recaptcha.getClient(application, "KEY_ID")
      .onSuccess { client ->
        recaptchaClient = client
      }
      .onFailure { exception ->
        // Handle errors ...
      }
  }
}

 // Migrate to fetchClient
private fun initializeWithFetchClient() {
  recaptchaScope.launch {
    try {
      recaptchaClient = Recaptcha.fetchClient(application, "KEY_ID")
    } catch(e: RecaptchaException){
      // Handle errors ...
    }
  }
}

Java

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

  // Migrate to fetchTaskClient
  private void initializeWithFetchTaskClient() {
    Recaptcha
      .fetchTaskClient(getApplication(), "KEY_ID")
      .addOnSuccessListener(
          this,
          new OnSuccessListener<RecaptchaTasksClient>() {
            @Override
            public void onSuccess(RecaptchaTasksClient client) {
              recaptchaTasksClient = client;
            }
          })
      .addOnFailureListener(
          this,
          new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
              // Handle errors ...
            }
          });
  }

設定 API 呼叫的逾時時間

您可以使用 withTimeout 屬性,為 execute API 指定逾時值。

Kotlin

  • 呼叫 execute 時設定逾時。

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

    這個程式碼片段會將 execute 的逾時時間設為 10 秒。

Java

  • 呼叫 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 errors ...
                // See "Handle errors" section
              }
            });
    

    這個程式碼片段會將 execute 的逾時時間設為 10 秒。

處理錯誤

如果應用程式無法順利與 reCAPTCHA 服務通訊,可能是因為 API 發生錯誤。您必須在應用程式中加入邏輯,妥善處理這類錯誤。

如要進一步瞭解如何減輕常見 API 錯誤的影響,請參閱 RecaptchaErrorCode

API 參考資料

如需 Android 適用的 reCAPTCHA API 完整參考資料,請參閱 com.google.android.recaptcha

後續步驟

  • 如要評估 reCAPTCHA 回應權杖,請建立評估