Open In App

Android Jetpack Compose – Integrate Google reCAPTCHA

Last Updated : 10 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Google reCAPTCHA is a service provided by Google which is used to verify the user whether is a user or a robot by providing them with a simple captcha to solve. In this article, we will be taking a look at How to integrate Google reCAPTCHA in the android application using Jetpack Compose.

Steps to Integrate Google reCAPTCHA

Step 1: Create a New Project in Android Studio

To create a new project in the Android Studio, please refer to How to Create a new Project in Android Studio with Jetpack Compose.

Step 2: Add the below Dependency to your build.gradle.kts File

Below is the dependency for Volley which will be needed for using of reCAPTCHA. For adding this dependency navigate to the app > Gradle Scripts > build.gradle.kts(Module :app) and add the below dependency in the dependencies section. 

dependencies {
...
implementation("com.android.volley:volley:1.2.1")
implementation ("com.google.android.gms:play-services-safetynet:18.1.0")
}

After adding the dependency simply sync your project to install it. 


Step 3: Generating API key for using Google reCAPTCHA

For using Google reCAPTCHA we have to build two keys as site key and the site secret key which we have to use for authentication. For creating a new API key navigate to this Google developer’s site. And refer to the following diagram to generate the API keys.

After adding this data accept reCAPTCHA terms and then click on Submit option.


Step 4: Adding permissions for the Internet

As we are calling the API for Google reCAPTCHA so we have to add permissions for the Internet in our AndroidManifest.xml. Navigate to the app > AndroidManifest.xml and add the below code to it. 

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


Step 5: Working with the MainActivity.kt file

Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.

MainActivity.kt:

Kotlin
package com.geeksforgeeks.demo

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.*
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.*
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.*
import com.android.volley.DefaultRetryPolicy
import com.android.volley.Response
import com.android.volley.toolbox.*
import com.google.android.gms.common.api.*
import com.google.android.gms.safetynet.SafetyNet
import org.json.JSONObject
import java.util.*
import com.geeksforgeeks.demo.ui.theme.DemoTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DemoTheme(dynamicColor = false, darkTheme = false) {
                Surface(color = Color.White) {
                    Recaptcha()
                }
            }
        }
    }
}

// Creating a composable for displaying UI.
@Composable
fun Recaptcha() {
    
    // Creating a variable for context
    val context = LocalContext.current

    // Creating a variable for site key.
    val siteKey = "Enter your site key"

    // Creating a column for
    // displaying a text and a button.
    Column(
        modifier = Modifier
            .fillMaxSize()
            .fillMaxHeight()
            .fillMaxWidth(),

        // Specifying vertical and horizontal alignment.
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // Specifying text for a text view
        Text(
            text = "reCAPTCHA in Android",
            color = Color.Black,
            fontFamily = FontFamily.Default,
            fontWeight = FontWeight.Bold, textAlign = TextAlign.Center
        )
        
        // Adding a spacer on below line.
        Spacer(modifier = Modifier.height(5.dp))

        // Creating a button to verify the user.
        Button(
            
            // Adding on click for the button.
            onClick = {
                
                // Calling safety net on below line to verify recaptcha.
                SafetyNet.getClient(context).verifyWithRecaptcha(siteKey).addOnSuccessListener {
                    if (it.tokenResult!!.isNotEmpty()) {
                        
                        // Calling handle verification method
                        // to handle verification.
                        handleVerification(it.tokenResult.toString(), context)
                    }
                }.addOnFailureListener {
                    
                    // On below line handling exception
                    if (it is ApiException) {
                        val apiException = it as ApiException
                        
                        // Below line is use to display an
                        // error message which we get.
                        Log.d(
                            "TAG", "Error message: " +
                                    CommonStatusCodes.getStatusCodeString(apiException.statusCode)
                        )
                    } else {
                        
                        // Below line is use to display a
                        // toast message for any error.
                        Toast.makeText(context, "Error found is : $it", Toast.LENGTH_SHORT)
                            .show()
                    }
                }
            },
            
            // On below line adding
            // modifier for our button.
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)
        ) {
            
            // On below line specifying text for button.
            Text(text = "Verify Captcha", modifier = Modifier.padding(8.dp))
        }
    }
}

// Creating a method to handle verification.
fun handleVerification(responseToken: String, ctx: Context) {
    
    // inside handle verification method we are
    // verifying our user with response token.
    // url to sen our site key and secret key
    // to below url using POST method.
    val url = "https://www.google.com/recaptcha/api/siteverify"

    // creating a new variable for our request queue
    val queue = Volley.newRequestQueue(ctx)
    val secretKey = "Enter your secret key"

    val request: StringRequest =
        object : StringRequest(
            Method.POST, url,
            Response.Listener { response ->
                // inside on response method we are checking if the
                // response is successful or not.
                try {
                    val jsonObject = JSONObject(response)
                    if (jsonObject.getBoolean("success")) {
                        
                        // if the response is successful
                        // then we are showing below toast message.
                        Toast.makeText(
                            ctx,
                            "User verified with reCAPTCHA",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        
                        // if the response if failure
                        // we are displaying
                        // a below toast message.
                        Toast.makeText(
                            ctx,
                            jsonObject.getString("error-codes").toString(),
                            Toast.LENGTH_LONG
                        ).show()
                    }
                } catch (ex: Exception) {
                    
                    // if we get any exception then we are
                    // displaying an error message in logcat.
                    Log.d("TAG", "JSON exception: " + ex.message)
                }
            }, Response.ErrorListener { 
            
            // displaying toast message on response failure.
            Toast.makeText(ctx, "Fail to post data..", Toast.LENGTH_SHORT)
                .show()
        }) {
            override fun getParams(): Map<String, String>? {

                val params: MutableMap<String, String> = HashMap()
                params["secret"] = secretKey
                params["response"] = responseToken
                return params
            }
        }
        
    // below line of code is use to set retry
    // policy if the api fails in one try.
    request.setRetryPolicy(
        DefaultRetryPolicy( // we are setting time for retry is 5 seconds.
            50000,  // below line is to perform maximum retries.
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
        )
    )
    
    // below line is to make
    // a json object request.
    queue.add(request)
}

Output:



Next Article
Article Tags :

Similar Reads