Hello friends, I got a lots of emails and facebook requests to post a tutorial for phone number verification. Some people also asked me for SMS verification code for android. So in this tutorial we will create an Android SMS Verification App.
You already seen this example in some popular applications like WhatsApp, Hike etc. They verify the user’s phone number by sending an OTP (One Time Password) to the phone number registered.
To avoid spamming this is the best way to confirm your user with their phone number. And that is why verifying user’s with their phone number is one of the most common feature for your android app now days.
So in this tutorial we will create an Android SMS Verification App for registered users.
Android SMS Verification App – Video
You can check this video to know what we will be creating in this Android SMS Verification tutorial.
Creating our SMS API
- To verify the user’s phone number we will send the verification code via SMS. For sending SMS we need an SMS API.
- SMS’s are of two types
- Promotional: It will not be sent to DND activated phone numbers. So for OTPÂ Â or Phone verification we cannot use promotional sms.
- Transactional: It will be sent to all numbers, doesn’t matter a number has activated DND or not. In this tutorial I am using Transactional sms.
- The bad news is for you guys is I haven’t found any provider who is providing SMS API for free. This tutorial is sponsored by Cheap SMS Bazaar. They gave me some free transactional sms credits to write this tutorial.
- There are a lot of SMS API provider’s you can google for them. You can also buy it from Cheap SMS Bazaar. If you will signup to Cheap SMS Bazaar, they would give you 10 free promotional sms. You can test this tutorial with promotional sms as well. But with promotional sms your sms will not be sent to DND activated numbers.
- I am assuming that you all are using Cheap SMS Bazaar. So go to your dashboard. And then go to API Documents. I am using the transactional one and my API link is.
http://login.cheapsmsbazaar.com/vendorsms/pushsms.aspx?user=abc&password=xyz&msisdn=919898xxxxxx&sid=SenderId&msg=test%20message&fl=0&gwid=2
user: Your login username.
password: Your login password.
msisdn: Single mobile number or multiple mobile numbers separated by comma(10 digits or +91).
sid: Approved sender id(Only 6 characters).
msg: Your message content(Minimum 459 characters/3 messages).
fl: if flash message then 1 or else 0
gwid: 2 (its for Transactions route.)
Note: Only 100 mobile numbers are allowed.
- We will send the sms to only a single mobile number.
- We will get the following JSON in response.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "ErrorCode":"000", "ErrorMessage":"Success", "JobId":"381a8090-b230-42fa-ac04-157cc2142bfa", "MessageData":[ { "MobileNumber":"919898xxxxxx ", "MessageParts":[ { "MessageId":"919898xxxxxx -67e3765cdf034f438a432eacb88d0c14", "MessagePartId":1, "MessageText":"test message" } ] } ] } |
Creating Database and Scripts for Android SMS Verification Application
- Go to phpMyAdmin and create the following table. (I am using Hostinger’s free hosting).
- As you can see I have 6 columns. ID is PRIMARY KEY and AUTOINCREMENT Username and Phone is set to UNIQUE. verified is TINY INT and will store only two values 0 and 1. (o means not verified and 1 means verified). The default value for verified is set to 0 i.e. for every row the default value is unverified. And when user will enter the correct verification code we will change it to 1 i.e. verified.
- Go to your server’s directory and create a folder for this project. (I created AndroidOTP)
- We need to connect to the database first, so create a script dbConnect.php and write the following code.
1 2 3 4 5 6 7 8 9 10 |
<?php define('HOST','mysql.hostinger.in'); define('USER','u502452270_andro'); define('PASS','belal_123'); define('DB','u502452270_andro'); //Connecting to database $con = mysqli_connect(HOST,USER,PASS,DB) or die('Unable to Connect'); |
- Now to handle the registration request create a file register.php. This file would store the user detail to database. It will also send the OTP or Verification Code via SMS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?php //Constants for our API //this is applicable only when you are using Cheap SMS Bazaar define('SMSUSER','your user name'); define('PASSWORD','your password'); define('SENDERID','your sender id'); //This function will send the otp function sendOtp($otp, $phone){ //This is the sms text that will be sent via sms $sms_content = "Welcome to Simplified Coding: Your verification code is $otp"; //Encoding the text in url format $sms_text = urlencode($sms_content); //This is the Actual API URL concatnated with required values $api_url = 'http://login.cheapsmsbazaar.com/vendorsms/pushsms.aspx?user='.SMSUSER.'&password='.PASSWORD.'&msisdn=91'.$phone.'&sid='.SENDERID.'&msg='.$sms_text.'&fl=0&gwid=2'; //Envoking the API url and getting the response $response = file_get_contents( $api_url); //Returning the response return $response; } //If a post request comes to this script if($_SERVER['REQUEST_METHOD']=='POST'){ //getting username password and phone number $username = $_POST['username']; $password = $_POST['password']; $phone = $_POST['phone']; //Generating a 6 Digits OTP or verification code $otp = rand(100000, 999999); //Importing the db connection script require_once('dbConnect.php'); //Creating an SQL Query $sql = "INSERT INTO androidotp (username, password, phone, otp) values ('$username','$password','$phone','$otp')"; //If the query executed on the db successfully if(mysqli_query($con,$sql)){ //printing the response given by sendOtp function by passing the otp and phone number echo sendOtp($otp,$phone); }else{ //printing the failure message in json echo '{"ErrorMessage":"Failure"}'; } //Closing the database connection mysqli_close($con); } |
- After sending the OTP to user’s mobile number we need to confirm the OTP from user. And for this we need one more php file. Create a new file confirm.php and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php //If a post request is detected if($_SERVER['REQUEST_METHOD']=='POST'){ //Getting the username and otp $username = $_POST['username']; $otp = $_POST['otp']; //Importing the dbConnect script require_once('dbConnect.php'); //Creating an SQL to fetch the otp from the table $sql = "SELECT otp FROM androidotp WHERE username = '$username'"; //Getting the result array from database $result = mysqli_fetch_array(mysqli_query($con,$sql)); //Getting the otp from the array $realotp = $result['otp']; //If the otp given is equal to otp fetched from database if($otp == $realotp){ //Creating an sql query to update the column verified to 1 for the specified user $sql = "UPDATE androidotp SET verified = '1' WHERE username ='$username'"; //If the table is updated if(mysqli_query($con,$sql)){ //displaying success echo 'success'; }else{ //displaying failure echo 'failure'; } }else{ //displaying failure if otp given is not equal to the otp fetched from database echo 'failure'; } //Closing the database mysqli_close($con); } |
- Thats it for the server side part. Note the URL for the both the files register.php and confirm.php. And lets create an Android Project.
Android SMS Verification Project
- Open Android Studio and create a new project and add the following dependencies that will be used.
1 2 3 4 5 6 7 8 9 |
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.0' compile 'com.android.support:design:23.0.0' compile 'com.mcxiaoke.volley:library-aar:1.0.0' } |
- I have added volley because in this android sms verification tutorial I am using volley for the network operations. And for the layout design I have added design:23.0.0.
- Now in your project create a java class to store the important constants that will be used in our app. I created Config.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package net.simplifiedcoding.androidotp; /** * Created by Belal on 11/18/2015. */ public class Config { //URLs to register.php and confirm.php file public static final String REGISTER_URL = "http://simplifiedcoding.16mb.com/AndroidOTP/register.php"; public static final String CONFIRM_URL = "http://simplifiedcoding.16mb.com/AndroidOTP/confirm.php"; //Keys to send username, password, phone and otp public static final String KEY_USERNAME = "username"; public static final String KEY_PASSWORD = "password"; public static final String KEY_PHONE = "phone"; public static final String KEY_OTP = "otp"; //JSON Tag from response from server public static final String TAG_RESPONSE= "ErrorMessage"; } |
- Now we need to design a registration activity. I have created the following layout for this android sms verification.
- For creating the above layout you can use the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:background="@color/colorBackground" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fitsSystemWindows="true"> <LinearLayout android:layout_gravity="center_vertical" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="24dp" android:paddingRight="24dp"> <ImageView android:background="@drawable/logo" android:layout_gravity="center_horizontal" android:layout_width="150dp" android:layout_height="150dp" /> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp"> <EditText android:id="@+id/editTextUsername" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="username" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp"> <EditText android:id="@+id/editTextPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="Password"/> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp"> <EditText android:id="@+id/editTextPhone" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="Phone" /> </android.support.design.widget.TextInputLayout> <android.support.v7.widget.AppCompatButton android:id="@+id/buttonRegister" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:textColor="@color/colorAccent" android:layout_marginTop="24dp" android:layout_marginBottom="24dp" android:padding="12dp" android:text="Register"/> <TextView android:id="@+id/linkSignup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:text="Already have an account? Login here" android:gravity="center" android:textSize="16dip"/> </LinearLayout> </ScrollView> |
- After user will tap the REGISTER button, a dialog box will appear to enter the confirmation code sent. For this dialog box we need to create a layout resource file. Create dialog_confirm.xml file and write the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="@dimen/activity_horizontal_margin" android:layout_margin="@dimen/activity_horizontal_margin" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimaryDark" android:orientation="vertical"> <TextView android:textColor="@color/colorAccent" android:text="Enter the code received" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <EditText android:id="@+id/editTextOtp" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" /> <android.support.v7.widget.AppCompatButton android:id="@+id/buttonConfirm" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:layout_marginTop="24dp" android:background="@color/colorPrimary" android:padding="12dp" android:text="Confirm" android:textColor="@color/colorAccent" /> </LinearLayout> |
- Now come to MainActivity.java.Â
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
package net.simplifiedcoding.androidotp; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.AppCompatButton; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; import android.widget.Toast; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity implements View.OnClickListener { //Creating views private EditText editTextUsername; private EditText editTextPassword; private EditText editTextPhone; private EditText editTextConfirmOtp; private AppCompatButton buttonRegister; private AppCompatButton buttonConfirm; //Volley RequestQueue private RequestQueue requestQueue; //String variables to hold username password and phone private String username; private String password; private String phone; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Initializing Views editTextUsername = (EditText) findViewById(R.id.editTextUsername); editTextPassword = (EditText) findViewById(R.id.editTextPassword); editTextPhone = (EditText) findViewById(R.id.editTextPhone); buttonRegister = (AppCompatButton) findViewById(R.id.buttonRegister); //Initializing the RequestQueue requestQueue = Volley.newRequestQueue(this); //Adding a listener to button buttonRegister.setOnClickListener(this); } //This method would confirm the otp private void confirmOtp() throws JSONException { //Creating a LayoutInflater object for the dialog box LayoutInflater li = LayoutInflater.from(this); //Creating a view to get the dialog box View confirmDialog = li.inflate(R.layout.dialog_confirm, null); //Initizliaing confirm button fo dialog box and edittext of dialog box buttonConfirm = (AppCompatButton) confirmDialog.findViewById(R.id.buttonConfirm); editTextConfirmOtp = (EditText) confirmDialog.findViewById(R.id.editTextOtp); //Creating an alertdialog builder AlertDialog.Builder alert = new AlertDialog.Builder(this); //Adding our dialog box to the view of alert dialog alert.setView(confirmDialog); //Creating an alert dialog final AlertDialog alertDialog = alert.create(); //Displaying the alert dialog alertDialog.show(); //On the click of the confirm button from alert dialog buttonConfirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Hiding the alert dialog alertDialog.dismiss(); //Displaying a progressbar final ProgressDialog loading = ProgressDialog.show(MainActivity.this, "Authenticating", "Please wait while we check the entered code", false,false); //Getting the user entered otp from edittext final String otp = editTextConfirmOtp.getText().toString().trim(); //Creating an string request StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.CONFIRM_URL, new Response.Listener<String>() { @Override public void onResponse(String response) { //if the server response is success if(response.equalsIgnoreCase("success")){ //dismissing the progressbar loading.dismiss(); //Starting a new activity startActivity(new Intent(MainActivity.this, Success.class)); }else{ //Displaying a toast if the otp entered is wrong Toast.makeText(MainActivity.this,"Wrong OTP Please Try Again",Toast.LENGTH_LONG).show(); try { //Asking user to enter otp again confirmOtp(); } catch (JSONException e) { e.printStackTrace(); } } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { alertDialog.dismiss(); Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String,String> params = new HashMap<String, String>(); //Adding the parameters otp and username params.put(Config.KEY_OTP, otp); params.put(Config.KEY_USERNAME, username); return params; } }; //Adding the request to the queue requestQueue.add(stringRequest); } }); } //this method will register the user private void register() { //Displaying a progress dialog final ProgressDialog loading = ProgressDialog.show(this, "Registering", "Please wait...", false, false); //Getting user data username = editTextUsername.getText().toString().trim(); password = editTextPassword.getText().toString().trim(); phone = editTextPhone.getText().toString().trim(); //Again creating the string request StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.REGISTER_URL, new Response.Listener<String>() { @Override public void onResponse(String response) { loading.dismiss(); try { //Creating the json object from the response JSONObject jsonResponse = new JSONObject(response); //If it is success if(jsonResponse.getString(Config.TAG_RESPONSE).equalsIgnoreCase("Success")){ //Asking user to confirm otp confirmOtp(); }else{ //If not successful user may already have registered Toast.makeText(MainActivity.this, "Username or Phone number already registered", Toast.LENGTH_LONG).show(); } } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { loading.dismiss(); Toast.makeText(MainActivity.this, error.getMessage(),Toast.LENGTH_LONG).show(); } }) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<>(); //Adding the parameters to the request params.put(Config.KEY_USERNAME, username); params.put(Config.KEY_PASSWORD, password); params.put(Config.KEY_PHONE, phone); return params; } }; //Adding request the the queue requestQueue.add(stringRequest); } @Override public void onClick(View v) { //Calling register method on register button click register(); } } |
- On success we are starting a new activity that is not yet created. So create a new activity named success. And write the following xml code for the layout file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="@color/colorBackground" tools:context="net.simplifiedcoding.androidotp.Success"> <LinearLayout android:layout_gravity="center_vertical" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentStart="true"> <ImageView android:background="@drawable/logo" android:layout_gravity="center_horizontal" android:layout_width="150dp" android:layout_height="150dp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="24dp" android:text="You have successfully verified your phone number" android:gravity="center" android:textSize="16dip"/> </LinearLayout> </RelativeLayout> |
- The above code will produce the following layout.
- For the java file of this activity (Success.java) I haven’t done anything.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package net.simplifiedcoding.androidotp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class Success extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_success); } } |
- At last add internet permission to your manifest file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.simplifiedcoding.androidotp"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="Register" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".Success"></activity> </application> </manifest> |
- Now run your application.
- Bingo! Its working absolutely fine. You can get the project from GitHub Repository. Just go to the link given below.
Get Source Code of this Android SMS Verification App from GitHub
[sociallocker id=1372] Android SMS Verification Application[/sociallocker]
Some More Android Application Development Tutorial You Must CheckÂ
- Android Login Example Using PHP, MySQL and Volley
- Android Email App using JavaMail API
- Android Custom ListView iwth Images using RecyclerView and Volley
So thats all for this Android SMS Verification Tutorial. Please support by giving your feedbacks with your comments. And don’t hesitate to ask if having queries or confusions regarding this Android SMS Verification Tutorial. Thank You 🙂