Dauris Little

  • About
  • Dauris’s Portfolio
  • Blogging Lyf
  • Contact

Integrating Google’s reCAPTCHA w/Android

Android reCAPTCHA
Avatar photo
Dauris
Thursday, 12 December 2019 / Published in Android, API, blog, Java, Mobile Development, Programming Languages

Integrating Google’s reCAPTCHA w/Android

Introduction

Google’s reCAPTCHA API protects your website/app from malicious traffic. You might have seen the reCAPTCHA integrated on web pages. You can integrate the same in your Android apps too using SafeNet API. The service is free to use and it will show a captcha to be solved if the engine suspects user interaction to be a bot instead of a human.

Within this post, I will explain and build a simple button click application that will integrate captcha to avoid bots from submitting forms on there own. But understand that this method is not only limited to form usage but a user can integrate any this module into any app

How it works

The following point will explain the simple flow of reCAPTCHA in Android with SafetyNet API.

  • First, a user needs to obtain the SafetyNet key pair by registering your app. After completing this a Site & Secret Key.
  • The Site Key will be integrated into an Android app and it can be public. Secret Key should be kept on your server and it shouldn’t be exposed.
  • When reCAPTCHA is invoked, it will show the Captcha challenge to a user it necessary. In this step, it communicates with the captcha server and returns “User Response Token” using Site Key.

Registering your App w/SafetyNet

To begin before diving into the application creation we need to get the keys that will be validated against.

Fist go to the site following site and sign up if you do not already have an account

  • https://www.google.com/recaptcha/intro/v3.html
  • After accessing your account create
  • Register a new account
  • Now enter your label, reCAPTCHA type, domains and then accept “Terms of Service”
NOTE: Regarding the label the title be anything that identifies the api key to yourself
NOTE: Regarding the selecting reCAPTCHA if working with android select reCAPTCHA v2 then reCAPTCHA Android
NOTE: Regarding populating the domain should be your Package Name in Package Names Section

Then, you will get the site key and secret key from SafetyNet API Server and it as well as shows client and server-side integration code snippets. The following figures show the same.

Step 1 – Create New Project w/Android Studio

Now lets begin with the fun stuff and to begin you will begin by open Android Studio and then “Create New Project”

  • Begin by Start a new Android Studio Project èselect Basic Activity from templates. 

NOTE: While creating, use the package name you have registered on reCAPTCHA dashboard.

Step 2 – Setting up the library & AndroidMainfest for the project

Add SafeNet and the Volley dependency to your build.gradle and rebuild the project. Here, I used the following dependency. You can change as per your Android SDK.

NOTE: Volley is used to send HTTP call to our server to validate the captcha token on the server side.

build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    //dependency for recaptcha (safetynet)
    implementation 'com.google.android.gms:play-services-safetynet:17.0.0'

    //dependency for fast networking for networking
    implementation 'com.android.volley:volley:1.1.0'
}

Now we need to add the app manifest file with the following permission(s). SafetyNet library is used to create the captcha validation in android. Volley library is an HTTP Networkinf library used here for validating captcha response.

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

Step 3 – Implementation of SafetyNet API

If you are still with me then let’s dive into the Java part of the project. We will first ensure that we have all the modules that will be used in the application

Required modules
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;

//volley
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.RequestQueue;
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.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import android.view.Menu;
import android.view.MenuItem;

Step 3 – Implementation of SafetyNet API (Continue)

If you are still with me then let’s dive into the Java part of the project. We will first ensure that we have all the modules that will be used in the application

  • Replace “Site_Key” and “Site_Secret_Key” with your appropriate “Site Key” and “Secret Key” get from SafetyNet API while registering app.
  • The API will check the Server and it has a separate callbacks from success and failure.
  • At Success, we will get Captcha Response Token which will be used to validate the user interaction is made by a bot or real human.
  • We will discuss how to validate the token with SafetyNet API Server in next step.

NOTE: the call on the created click event

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

        btn = findViewById(R.id.reCaptcha);
        txtV = findViewById(R.id.verifyText);
        btn.setOnClickListener(this);

        requestQueue = Volley.newRequestQueue(getApplicationContext());
    }

    public void onClick(View view){
        SafetyNet.getClient(this).verifyWithRecaptcha(Site_Key)
                .addOnSuccessListener(this, new OnSuccessListener <SafetyNetApi.RecaptchaTokenResponse>(){
                    @Override
                    public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response){
                        if (!response.getTokenResult().isEmpty()){
                            handleCaptchaResult(response.getTokenResult());

                        }
                    }
        })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        if (e instanceof  ApiException){
                            ApiException apiException = (ApiException)e;
                            Log.d(TAG, "Error Message: " + CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
                        } else {
                            Log.d(TAG, "Unknown error type or error" + e.getMessage());
                        }
                    }
                });
    }

Step 4 – Captcha Response Token Validation

  1. We have to verify the token getting from the server using the secret key.
  2. It can achieve by using the following.
    • API Link – https://www.google.com/recaptcha/api/siteverify
    • Method – POST
    • Params – secret, response (We have to pass the “SECRET_KEY” and “TOKEN” respectively)

NOTE: Volley has

    • RequestQueue to maintain the server calls in queue.
    • RetryPolicy to retry the server call if it is fail with TimeOut and Retry Count. We can change those values.
    • StringRequest is used for getting Response as JSON String.
    • Method.POST denotes the call as POST method.
    • Params are passed to server using Map, HashMap.

The SafetyNet API provides the response respective to the parameters passed and the success is Boolean Datatype.

void handleCaptchaResult(final String responseToken){
        String url = "https://www.google.com/recaptcha/api/siteverify"; //consider using global variable here
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    if (jsonObject.getBoolean("success")) {
                        txtV.setTextSize(35);
                        txtV.setText("Congratulations! You're not a robot anymore");
                    }
                } catch (Exception ex) {
                    Log.d(TAG, "Error message: " + ex.getMessage());
                }
            }
        },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "Error message: " + error.getMessage());
                    }
                })
        {
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<>();
                params.put("secret", Site_Secret_Key);
                params.put("response", responseToken);
                return params;
            }
        };
        request.setRetryPolicy(new DefaultRetryPolicy(50000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(request);
    }

Full Review / Conclusion

In this blog tutorial, I was able to show you how to use Google’s reCAPTCHA in our Android app. Understand using reCAPTCHA in any app, we need to get one Site key and one Secret key and after that, we request for the captcha from the reCAPTCHA server. Once we get the reCAPTCHA and the user has entered the captcha, we send the entered value to the reCPATCA server and get the captcha token. This token is sent to our server and our server along with the secret key send the token to the reCAPTCHA server again. After that, we get some success message and that message is conveyed to our Android app.

NOTE: I have also displayed below the code for the layout for the main activity as well. This is the just a simple layout but the practical could be implemented with very little ease.

Github Project 

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;

//volley
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.RequestQueue;
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.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.safetynet.SafetyNet;
import com.google.android.gms.safetynet.SafetyNetApi;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.widget.Toolbar;


import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    String TAG = MainActivity.class.getSimpleName();
    Button btn;
    TextView txtV;
 // TODO - replace the SITE KEY with yours
    String Site_Key = "6LcFP8cUAAAAALPrBpvuSPileb7vd"; //consider making global variable(this will not work not a valid key)
 // TODO - replace the Secret KEY with yours
    String Site_Secret_Key = "6LcFP8cUAAAAAJyKpv8FKRkd1bSnR-"; //consider making global variable(this will not work not a valid key)
    RequestQueue requestQueue;

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

        btn = findViewById(R.id.reCaptcha);
        txtV = findViewById(R.id.verifyText);
        btn.setOnClickListener(this);

        requestQueue = Volley.newRequestQueue(getApplicationContext());
    }

    @Override
    public void onClick(View view){
        SafetyNet.getClient(this).verifyWithRecaptcha(Site_Key)
                .addOnSuccessListener(this, new OnSuccessListener <SafetyNetApi.RecaptchaTokenResponse>(){
                    @Override
                    public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response){
                        if (!response.getTokenResult().isEmpty()){
                            handleCaptchaResult(response.getTokenResult());

                        }
                    }
        })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        if (e instanceof  ApiException){
                            ApiException apiException = (ApiException)e;
                            Log.d(TAG, "Error Message: " + CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
                        } else {
                            Log.d(TAG, "Unknown error type or error" + e.getMessage());
                        }
                    }
                });
    }

    void handleCaptchaResult(final String responseToken){
        String url = "https://www.google.com/recaptcha/api/siteverify"; //consider using global variable here
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject jsonObject = new JSONObject(response);
                    if (jsonObject.getBoolean("success")) {
                        txtV.setTextSize(35);
                        txtV.setText("Congratulations! You're not a robot anymore");
                    }
                } catch (Exception ex) {
                    Log.d(TAG, "Error message: " + ex.getMessage());
                }
            }
        },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d(TAG, "Error message: " + error.getMessage());
                    }
                })
        {
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<>();
                params.put("secret", Site_Secret_Key);
                params.put("response", responseToken);
                return params;
            }
        };
        request.setRetryPolicy(new DefaultRetryPolicy(50000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        requestQueue.add(request);
    }
}
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:orientation="vertical">

        <Button
            android:id="@+id/reCaptcha"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:text="Show reCAPTCHA"/>

        <TextView
            android:id="@+id/verifyText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:capitalize="characters"
            android:text="Hello World"
            android:textSize="24sp" />

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Your browser does not support the video tag.
Tagged under: android, goodle reCAPTCHA, google, java, programming, reCAPTCHA, safetyNet, Volley

What you can read next

Swift Has Tuple
website design
Different Type of Websites
View Binding w/Android

9 Comments to “ Integrating Google’s reCAPTCHA w/Android”

  1. Best SEO Services says :Reply
    January 24, 2020 at 10:51 am

    Awesome post! Keep up the great work! 🙂

  2. AffiliateLabz says :Reply
    February 16, 2020 at 5:17 am

    Great content! Super high-quality! Keep it up! 🙂

  3. Kellie Kimsey says :Reply
    June 2, 2020 at 6:18 am

    Thanks for some other informative website. The place else may just I get that kind of information written in such an ideal way? I’ve a challenge that I am just now working on, and I’ve been at the look out for such info.

  4. Kittie Alphonso says :Reply
    June 3, 2020 at 8:13 am

    Hi! I just wanted to ask if you ever have any trouble with hackers? My last blog (wordpress) was hacked and I ended up losing months of hard work due to no backup. Do you have any solutions to prevent hackers?

  5. Robyn says :Reply
    June 5, 2020 at 1:21 pm

    Someone essentially lend a hand to make severely articles I might state.
    This is the very first time I frequented your web page and to this point?
    I surprised with the analysis you made to make this actual publish amazing.
    Fantastic task!

  6. best skin care products reviews says :Reply
    June 21, 2020 at 1:57 pm

    Useful info. Fortunate me I discovered your web site accidentally, and I am surprised why this
    accident didn’t came about in advance! I bookmarked it.

  7. alpha femme keto Reviews says :Reply
    June 29, 2020 at 1:12 pm

    Very good website you have here but I was wondering if you knew of any user discussion forums
    that cover the same topics talked about here? I’d really like to be a part of online community where
    I can get feed-back from other knowledgeable people that share the same interest.
    If you have any recommendations, please let me
    know. Appreciate it!

  8. Cleora Weideman says :Reply
    July 14, 2020 at 1:13 pm

    Hiya, I am really glad I have found this info. Nowadays bloggers publish just about gossip and web stuff and this is actually frustrating. A good website with exciting content, that’s what I need. Thank you for making this web-site, and I’ll be visiting again. Do you do newsletters by email?

  9. Homepage says :Reply
    August 26, 2020 at 2:09 pm

    If you are going for most excellent contents like me, simply visit this web page all
    the time as it provides quality contents, thanks

Leave a Reply to Best SEO Services Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Categories

Recent Posts

  • Gesture Controls for Android w/Kotlin

    Incorporating Gesture controls in your android ...
  • Android Rating: In-App Review API

    An app rating and reviews are crucial if you wa...
  • QR Reader in Android w/ Kotlin

    Turn your phone's camera into a QR scanner...
  • Creating Advance Custom Snackbar w/ Kotlin

    Ask 100 different developers about what they fi...
  • Swift Has Tuple

    Swift provides us with a type called Tuple whic...

© 2017. All rights reserved. Designed by Dauris Little

TOP
This site uses tracking cookies to personalize content and ads. AcceptLearn More