Instrumenting Android apps

This page explains how to customize reCAPTCHA Enterprise API in your Android app. For more information about reCAPTCHA Enterprise, see the reCAPTCHA Enterprise overview

Before you begin

  1. Complete the steps in the Quickstart to gain access to the API.
  2. Create a reCAPTCHA Key.

Prepare your development environment

Download and install the latest version of Android Studio.

App integration

Start a new Android Studio project with an Empty Activity and minimum API level 16, to create a test application.

Add Google's Maven repository dependency

To add a dependency to the reCAPTCHA SDK, you must add Google's Maven repository to your project by including the following maven snippet in the repositories configuration area within the project-level build.gradle file:

allprojects {
    repositories {
        google()

        // If you're using a version of Gradle lower than 4.1, you must instead use:
        // maven {
        //     url 'https://maven.google.com'
        // }
        // An alternative URL is 'https://dl.google.com/dl/android/maven2/'
    }
}

For more information, see Google's Maven repository.

Add a reCAPTCHA API dependency

Before using the reCAPTCHA API, you need to add the reCAPTCHA API to your project. You should include the build rule from the following code snippet into the dependencies section of your app-level build.gradle:

apply plugin: 'com.android.application'
...
dependencies {
    implementation 'com.google.android.gms:play-services-recaptcha:16.0.0'
}

For more information, see Set Up Google Play Services.

Add internet permission

Our APIs involve network operations. In order to perform network operations in your application, your manifest (for example, AndroidManifest.xml) must include the following permission added between the first <manifest> tag and the first <application> tag.

<manifest ...?>

    <uses-permission android:name="android.permission.INTERNET" />

    <application ...>
    ...
  </application>
</manifest>

Update gradle.properties to use AndroidX

Add the following two lines to your gradle.properties file if you do not plan to compile the SDK to Android 9.0 (For additional details see Migrating to AndroidX):

android.useAndroidX=true
android.enableJetifier=true

Use the reCAPTCHA APIs

reCAPTCHA APIs contain three methods, init(), execute(), close(). To invoke reCAPTCHA, you call the three methods in order. Usually, the execute() method corresponds to the user selecting a UI element, such as a login button, in your activity.

Specifically, the overall flow for reCAPTCHA APIs is the following sequence of calls:

  1. Call init() as soon as you start your app or the activity containing the action you want to protect, to initialize a RecaptchaHandle.
    • Recaptcha.getClient(this).init("YOUR_SITE_KEY")
  2. Call execute() once the action you want to protect is done, for example, login button is clicked. It then returns a RecaptchaResults token.
    • Recaptcha.getClient(this).execute(handle, action)
  3. Call close() when you will not be using the RecaptchaHandle again.
    • Recaptcha.getClient(this).close(handle)

When calling the three methods in your app, you must override the onSuccess() and onFailure() methods to handle both possible outcomes of the API calls. In particular, if the API passes an instance of ApiException into onFailure(), you need to handle each possible status code that you can retrieve using getStatusCode(). For more information, see Handling communication errors.

The following code snippet shows how to invoke these three methods:

public final class MainActivity extends Activity {
   private RecaptchaHandle handle;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     // Step 1: Call init() once the activity starts.
     Recaptcha.getClient(this)
         .init("YOUR_SITE_KEY")
         .addOnSuccessListener(
             this,
             new OnSuccessListener<RecaptchaHandle>() {
               @Override
               public void onSuccess(RecaptchaHandle handle) {
                 // Handle success ...
                 MainActivity.this.handle = handle;
               }
             })
         .addOnFailureListener(
             this,
             new OnFailureListener() {
               @Override
               public void onFailure(@NonNull Exception e) {
                 if (e instanceof ApiException) {
                   ApiException apiException = (ApiException) e;
                   Status apiErrorStatus = apiException.getStatusCode();
                   // Handle api errors ...
                 } else {
                   // Handle other failures ...
                 }
               }
             });
   }

   public void onClick(View v) {
     // Step 2: call execute() when there is an action to protect.
     Recaptcha.getClient(this)
         .execute(this.handle, new RecaptchaAction(new RecaptchaActionType(RecaptchaActionType.LOGIN)))
         .addOnSuccessListener(
             this,
             new OnSuccessListener<RecaptchaResultData>() {
               @Override
               public void onSuccess(RecaptchaResultData response) {
                 String token = response.getTokenResult();
                 // Handle success ...
                 if (!token.isEmpty()) {
                   Log.d(TAG, "reCAPTCHA response token: " + token);
                   // Validate the response token by following the instruction
                   // in the Create an Assessment topic.
                 }
               }
             })
         .addOnFailureListener(
             this,
             new OnFailureListener() {
               @Override
               public void onFailure(@NonNull Exception e) {
                 if (e instanceof ApiException) {
                   ApiException apiException = (ApiException) e;
                   Status apiErrorStatus = apiException.getStatusCode();
                   // Handle api errors ...
                 } else {
                   // Handle other failures ...
                 }
               }
             });
   }

  @Override
  protected void onDestroy() {
    // Step 3: call close() when there is no more action to verify.
   Recaptcha.getClient(this)
       .close(handle)
       .addOnSuccessListener(
           this,
           new OnSuccessListener<Boolean>() {
             @Override
             public void onSuccess(Boolean gotClosed) {
               // Handle success ...
             }
           })
       .addOnFailureListener(
           this,
           new OnFailureListener() {
             @Override
             public void onFailure(@NonNull Exception e) {
               if (e instanceof ApiException) {
                 ApiException apiException = (ApiException) e;
                 Status apiErrorStatus = apiException.getStatusCode();
                 // Handle api errors ...
               } else {
                 // Handle other failures ...
               }
             }
           });
  }
}

Create an Assessment

To validate the reCAPTCHA response token, follow the instructions to create an Assessment with reCAPTCHA Enterprise.

Handling communication errors

If your app cannot communicate with the reCAPTCHA service successfully, it may be because the API is encountering an error. You should add logic in your app to gracefully handle such an error.

For more details about the mitagations for the common API errors, see RecaptchaStatusCodes.

API reference

For a complete reference of the APIs, see com.google.android.gms.recaptcha.