Get Started Developing for Kotlin Android Tutorial 2019 with Android Studio
May 17, 2018Android example for integrating captcha in android example
May 28, 2018Kotlin Integrating Google’s reCAPTCHA on the android app. Android Kotlin tutorial about integrating Google’s safetynet reCAPTCHA in your apps with a tutorial example. Also explained how to validate the token on the server using PHP Rest-API.
Google’s safetynet reCaptcha API protects your android-kotlin app from malicious traffic, robots. You might have seen the reCaptcha safetynet integrated on API, website, kotlin App. You can integrate the same in your Android kotlin apps too using SafetyNet API. The safetynet 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 human. Let’s Start work on integrating Google’s reCAPTCHA on Android Kotlin Example.
What is reCAPTCHA?
Easy to add, advanced security. reCAPTCHA is a free service that protects your site from spam and abuse. It uses advanced risk analysis techniques to tell humans and bots apart. With the new API, a significant number of your valid human users will pass the reCAPTCHA challenge without having to solve a CAPTCHA. reCAPTCHA comes in the form of a widget that you can easily add to your blog, forum, registration form, etc. And now safetynet reCAPTCHA Powered by machine learning.
A. How to get SafetyNet Site Key and Secret
Follow the below steps to obtain your Secret key and Site Key for API.
1. Open reCAPTCHA Registration page and fill out the details.
Link for reCAPTCHA Registration ( https://www.google.com/recaptcha/admin )
2. Then Enter Label, and choose the type of reCaptcha –> reCAPTCHA Android. (Google account login is required for safetynet reCAPTCHA Key).
3. Enter your android app package names (if you need to use this key in multiple apps then add one package name per line)
4. Accept the terms of reCAPTCHA and Register. Once reCAPTCHA registered, you can see Adding reCAPTCHA to your app –> Step 1: Client-side integration and Step 2: Server side integration are displayed on the screen along with sample code.
[Tips: Remember Site key for android app and Secret key for your server API Both are required and make sure your package name is added in recaptcha admin]. See below image for more bits of help.
B. Create a New Android Project
• Click on Android Studio Icon ( Open Android Studio ).
○ If you have already opened Android Studio from File ⇒ New Project.
• Start a new Android Studio Project. Then fill the displayed form.
○ See below-required details like this with an example.
○ Application name (Example: My AppName),
○ Company domain (Example: galleonsoft.com),
○ Project location (Example: C:\Users\JIGARPATEL\Desktop\Projects\MyAppName),
○ Package name (Example: com.galleonsoft.myappname),
○ Check Include Kotlin Support.
• Select the form factors and minimum SDK
○ Check Phone and Tablet.
• Add an Activity to Mobile you should Select Empty Activity.
○ You can select Basic Activity / Empty Activity. More options are available.
• Create a new empty activity.
○ Enter Activity Name (Example: MainActivity).
○ Enter Layout Name (Example: activity_main).
• Finish
○ Wait for few minutes to creating and building your projects.
C. Add dependencies to your build.gradle
build.gradle (Module App) App Level Gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.41" //noinspection GradleCompatible implementation 'com.android.support:appcompat-v7:27.1.1' // Google's SafetyNet reCAPTCHA implementation 'com.google.android.gms:play-services-safetynet:15.0.1' }
D. Set XML Layout (UI)
Open the layout file of ( activity_main.xml ) and add the below XML code.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" tools:ignore="HardcodedText"> <LinearLayout android:id="@+id/linearLayoutForm" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send us some feedback!" android:textColor="#666666" android:textSize="20sp" android:textStyle="bold" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Have a suggestion? We’ll take a look. Replace with your message." /> <EditText android:id="@+id/et_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:gravity="top" android:hint="Enter your feedback here!" android:lines="4" tools:ignore="TextFields" /> <Button android:id="@+id/btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="16dp" android:background="@color/colorAccent" android:padding="10dp" android:text="Send Message" android:textColor="@android:color/white" /> </LinearLayout> <TextView android:id="@+id/Tv_Message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="42dp" android:gravity="center" android:padding="16dp" android:text="Thanks for your message feedback. We\'ll get back to you soon!" android:textSize="22sp" android:visibility="gone" /> </LinearLayout>
E. Set Kotlin Code
Create a new class named ApiPostHelper.kt This Object/Class for POST API. Also, it helps in others projects. This class required for HttpURLConnection Method. You can use alternatively Volley, Retrofit, etc.
Create Kotlin object ApiPostHelper.kt and put the below code.
package com.galleonsoft.safetynetrecaptcha import android.util.Log import java.io.BufferedReader import java.io.BufferedWriter import java.io.OutputStreamWriter import java.io.UnsupportedEncodingException import java.net.HttpURLConnection import java.net.URL import java.net.URLEncoder import java.util.* import javax.net.ssl.HttpsURLConnection /** * Author: JIGAR PATEL. * Tutorial_URL: https://galleonsoft.com/tutorial/ */ object ApiPostHelper { // Send Parameters method fun SendParams(reqURL: String, postDataParams: HashMap<String, String>): String { val gsUrl: URL var resultString = "" try { gsUrl = URL(reqURL) val conn = gsUrl.openConnection() as HttpURLConnection conn.readTimeout = 7000 conn.connectTimeout = 7000 conn.requestMethod = "POST" conn.doInput = true conn.doOutput = true // For Post encoded Parameters val os = conn.outputStream val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8")) writer.write(getPostDataString(postDataParams)) writer.flush() writer.close() os.close() val responseCode = conn.responseCode Log.i("responseCode: ", responseCode.toString() + "") if (responseCode == HttpsURLConnection.HTTP_OK) { val allTextResponse = conn.inputStream.bufferedReader().use(BufferedReader::readText) resultString = allTextResponse } else { resultString = "" } } catch (e: Exception) { e.printStackTrace() } return resultString } // Collect Params from HashMap and encode with url. @Throws(UnsupportedEncodingException::class) private fun getPostDataString(params: HashMap<String, String>): String { val result = StringBuilder() var first = true for ((key, value) in params) { if (first) first = false else result.append("&") result.append(URLEncoder.encode(key, "UTF-8")) result.append("=") result.append(URLEncoder.encode(value, "UTF-8")) } return result.toString() } }
F. Create Kotlin class reCAPTCHA_Activity.kt and put the below code. (It’s your Activity class like MainActivity.java)
reCAPTCHA_Activity.kt
package com.galleonsoft.safetynetrecaptcha import android.annotation.SuppressLint import android.os.AsyncTask import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.text.TextUtils import android.util.Log import android.view.View import android.widget.* 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.JSONException import org.json.JSONObject import java.util.* class reCAPTCHA_Activity : AppCompatActivity() { lateinit var et_message: EditText lateinit var linearLayoutForm: LinearLayout lateinit var Tv_Message: TextView lateinit var btn_send: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val actionBar = supportActionBar if (actionBar != null) actionBar.title = getString(R.string.feedback) et_message = findViewById(R.id.et_message) linearLayoutForm = findViewById(R.id.linearLayoutForm) Tv_Message = findViewById(R.id.Tv_Message) btn_send = findViewById(R.id.btn_send) btn_send.setOnClickListener { CheckSafetynetreCAPTCHA() } } fun CheckSafetynetreCAPTCHA() { val feedback = et_message.text.toString().trim() // checking for empty text message if (TextUtils.isEmpty(feedback)) { Toast.makeText(applicationContext, "Enter feedback!", Toast.LENGTH_LONG).show() return } // Showing SafetyNet reCAPTCHA dialog SafetyNet.getClient(this).verifyWithRecaptcha(SAFETY_NET_API_KEY) .addOnSuccessListener(this) { response -> Log.d(TAG, "onSuccess") if (!response.tokenResult.isEmpty()) { // Received reCaptcha token and This token still needs to be validated on // the server using the SECRET key api. verifyTokenFromServer(response.tokenResult, feedback).execute() Log.i(TAG, "onSuccess: " + response.tokenResult) } } .addOnFailureListener(this) { e -> if (e is ApiException) { Log.d(TAG, "SafetyNet Error: " + CommonStatusCodes.getStatusCodeString(e.statusCode)) } else { Log.d(TAG, "Unknown SafetyNet error: " + e.message) } } } /** * Verifying the captcha token on the server * Server makes call to https://www.google.com/recaptcha/api/siteverify * with SECRET Key and SafetyNet token. */ @SuppressLint("StaticFieldLeak") private inner class verifyTokenFromServer(internal var sToken: String, internal var msg: String) : AsyncTask<String, String, String>() { override fun onPreExecute() { super.onPreExecute() } override fun doInBackground(vararg args: String): String { // object to hold the information, which is sent to the server val hashMap = HashMap<String, String>() hashMap["recaptcha-response"] = sToken // Optional params you can use like this // hashMap.put("feedback-message", msg) // Send the recaptcha response token and receive a Result in return return ApiPostHelper.SendParams(VERIFY_ON_API_URL_SERVER, hashMap) } override fun onPostExecute(result: String?) { if (result == null) return Log.i("onPost::: ", result) try { val jsonObject = JSONObject(result) val success = jsonObject.getBoolean("success") val message = jsonObject.getString("message") if (success) { // reCaptcha verified successfully. linearLayoutForm.visibility = View.GONE Tv_Message.visibility = View.VISIBLE } else { Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show() } } catch (e: JSONException) { e.printStackTrace() Log.i("Error: ", e.message) } } } companion object { private val TAG = "reCAPTCHA_Activity" // TODO: replace the reCAPTCHA KEY with yours private val SAFETY_NET_API_KEY = "6LdYZFoUAAAAAAXxuGh0OAnQ_8moTpkzhEtcqARB" // TODO: replace the SERVER API URL with yours private val VERIFY_ON_API_URL_SERVER = "http://apps.galleonsoft.com/api-example/safetynet-recaptcha-verfication.php" } }
☻ Don’t forget to change SAFETY_NET_API_KEY and VERIFY_ON_API_URL_SERVER on “reCAPTCHA_Activity.kt” kotlin class file replace the value with yours.
G. Open AndroidManifest.xml and We need to add INTERNET permission.
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.galleonsoft.safetynetrecaptcha"> <uses-permission android:name="android.permission.INTERNET" /> <application ..... ... </application> </manifest>
H. Validating reCAPTCHA Token on Server API
Below is the API (PHP code) to validate the reCaptcha token on the server API. See above guide “How to get SafetyNet Site Key and Secret” You need to set Secret Key and host the PHP code on your server/hosting to make it work for your kotlin/android app.
safetynet-recaptcha-verfication.php <?php $ch = curl_init(); $secretKey = 'ENTER_YOUR_reCAPTCHA_SECRET_KEY_HERE'; $captchaToken = isset($_POST['recaptcha-response']) && !empty($_POST['recaptcha-response']) ? $_POST['recaptcha-response']: ''; curl_setopt_array($ch, [ CURLOPT_URL => 'https://www.google.com/recaptcha/api/siteverify', CURLOPT_POST => true, CURLOPT_POSTFIELDS => [ 'secret' => $secretKey, 'response' => $captchaToken, 'remoteip' => $_SERVER['REMOTE_ADDR'] ], CURLOPT_RETURNTRANSFER => true ]); $output = curl_exec($ch); curl_close($ch); $json = json_decode($output); $response = array(); if($json->success){ $response['success'] = true; $response['message'] = 'reCAPTCHA verified successfully.'; }else{ $response['success'] = false; $response['message'] = 'Failed to verify reCAPTCHA.'; } echo json_encode($response); ?>
If you have any issues, queries or any suggestions please comment at below. You can download our source code for captcha in android example using below link.
Enjoy the tutorial for Android example about integrating Google’s reCAPTCHA in app. Use this latest tutorial and share it. ?
3 Comments
Good help on reCAPTCHA on Android kotlin.
Thanks, it’s really helped me.
Can you share recaptcha in android java example?
yeh..
Perfectly working thanks for coding in kotlin android.