Open In App

Android Jetpack Compose – Integrate Google reCAPTCHA

Last Updated : 13 Oct, 2022
Improve
Improve
Like Article
Like
Save
Share
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.

Step by Step Implementation

Step 1: Create a New Project in Android Studio

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. While choosing the template, select Empty Compose Activity. If you do not find this template, try upgrading the Android Studio to the latest version. We demonstrated the application in Kotlin, so make sure you select Kotlin as the primary language while creating a New Project.

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

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

implementation 'com.android.volley:volley:1.2.1'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'  

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. 

XML




<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.

Kotlin




package com.example.upipaymentgateway
 
import android.app.Activity
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.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.*
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.*
import com.android.volley.DefaultRetryPolicy
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.VolleyError
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.example.upipaymentgateway.ui.theme.*
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.safetynet.SafetyNet
import org.json.JSONObject
import java.util.*
 
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            UPIPaymentGatewayTheme {
                // on below line specifying theme
                Surface(
                    modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background
                ) {
                    Scaffold(
                        // specifying top bar on below line
                        topBar = {
                            // adding background color for top bar.
                            TopAppBar(backgroundColor = greenColor,
                                // adding title for top bar on below line
                                title = {
                                    // adding text in our top bar on below line,
                                    Text(
                                        // adding text style, text
                                        // and alignment for text
                                        text = "reCAPTCHA in Android",
                                        modifier = Modifier.fillMaxWidth(),
                                        textAlign = TextAlign.Center,
                                        color = Color.White
                                    )
                                })
                        }) {
                        // calling method
                        // to display UI,
                        recaptcha(this)
                    }
                }
            }
        }
    }
}
 
// creating a composable for displaying UI.
@Composable
fun recaptcha(mainActivity: MainActivity) {
     
    // creating a variable for context
    val ctx = LocalContext.current
     
    // creating a variable for site key.
    var SITE_KEY = "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 = greenColor,
            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(ctx).verifyWithRecaptcha(SITE_KEY).addOnSuccessListener {
                    if (it.tokenResult!!.isNotEmpty()) {
                        // calling handle verification method
                        // to handle verification.
                        handleVerification(it.tokenResult.toString(), ctx)
                    }
                }.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(ctx, "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.
     
    // creating a new variable for our request queue
    val queue = Volley.newRequestQueue(ctx)
    val SECRET_KEY = "Enter your secret key"
 
    val request: StringRequest =
        object : StringRequest(Request.Method.POST, url, object : Response.Listener<String?> {
            override fun onResponse(response: String?) {
                // 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)
                }
            }
        }, object : Response.ErrorListener {
            override fun onErrorResponse(error: VolleyError?) {
                // 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"] = SECRET_KEY
                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)
 
}


Now run your application to see its output of it. 

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads