Please Like our Facebook Page

Automatic Phone Number Verification Like Whatsapp or Telegram in Android


Generally you might have found apps that verify numbers automatically on receiving verification sms without user having to insert verification code. This tutorial will teach you on automatic phone number Verification like whatsapp, telegram e.t.c. I will be using sms gateway from Africas Talking Api. You can register for a free account here https://www.africastalking.com/. On registering you will be provided with free 10 sms, take advantage of that to test the system

You may also like:



1. How it works

You just need to understand the sender of the sms, for example, the sender of my verification code is AFRICASTKNG. In the sms broadcast receiver, I will check only sms from this sender and verify users. Just that. Let’s now jump into coding

2. Coding

For this application you need two permissions:

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

Having said that, this how your manifest file should look like:

manifest.xml



<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="hacksmile.com.smsverificationapp">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".OurBroadCastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".Verification"
            android:label="@string/title_activity_verification"
            android:theme="@style/AppTheme.NoActionBar" />

        <activity
            android:name=".Verified"
            android:label="@string/title_activity_verified"
            android:theme="@style/AppTheme.NoActionBar" />
    </application>

</manifest>

content_main.xml
Please note I used basic activity while creating this application.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:padding="10dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="hacksmile.com.smsverificationapp.MainActivity"
    tools:showIn="@layout/activity_main">

    <EditText
        android:id="@+id/phone_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:hint="@string/enter_your_phone_number"
        android:inputType="phone" />

    <Button
        android:id="@+id/btn_send_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/phone_number"
        android:text="Send" />

</RelativeLayout>

MainActivity.java
Mainactivity is where we are supplying phone number. Phone number must contain the the country code if you are using Africas Talking Api.

package hacksmile.com.smsverificationapp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        final EditText phoneNumber = (EditText) findViewById(R.id.phone_number);
        Button sendNumber = (Button) findViewById(R.id.btn_send_number);

        sendNumber.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // you might need to validate phone numbers
                Intent intent = new Intent(MainActivity.this, Verification.class);
                intent.putExtra("phone", phoneNumber.getText().toString());
                startActivity(intent);
            }
        });

        if (Permissions.isUserVerified(this)) {
            finish();
            startActivity(new Intent(this, Verified.class));
        }


    }

    @Override
    protected void onResume() {
        super.onResume();

        if (Permissions.isUserVerified(this)) {
            finish();
        }
    }


}


content_verification.xml
This is where we are sending verification code and verying the users

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="hacksmile.com.smsverificationapp.Verification"
    tools:showIn="@layout/activity_verification">


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="Verifying your account...\nPlease Wait, We will automatically verify you\nDo ont close this page"
        android:textSize="19sp"
        android:textStyle="bold|italic" />

</RelativeLayout>

Verification Activity (Verification.java)
Well, this is where verification takes place

package hacksmile.com.smsverificationapp;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.Toast;

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 java.util.HashMap;
import java.util.Map;

public class Verification extends AppCompatActivity {

    // under this activity we need to create a listener that will keep checking if the user is verified or not

    private Handler handler;
    private final Runnable runnable = new Runnable() {
        @Override
        public void run() {

            if (Permissions.isUserVerified(Verification.this)) {
                finish();
                startActivity(new Intent(Verification.this, Verified.class));
                Toast.makeText(Verification.this, "Verification succeeded ", Toast.LENGTH_SHORT).show();

                // stop handler from updating
                handler.removeCallbacks(runnable);
            }

            handler.postDelayed(runnable, 1000); // keep checking after every one second
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_verification);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Bundle bundle = getIntent().getExtras();
        if (bundle == null) {
            finish();
            return;
        }

        String phoneNumber = bundle.getString("phone");

        verifyPhoneNumber(phoneNumber);

        handler = new Handler();
        handler.postDelayed(runnable, 1000);

        runnable.run();

        if (Permissions.isUserVerified(this)) {
            finish();
            if (handler != null) {
                handler.removeCallbacks(runnable);
            }
            startActivity(new Intent(this, Verified.class));
        }
    }

    private void verifyPhoneNumber(final String phoneNumber) {
        String url = "https://hacksmile.com/verify_phone/verify.php";

        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Sending verification code...");
        progressDialog.setCancelable(false);
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progressDialog.dismiss();

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                progressDialog.dismiss();
                finish();
                Toast.makeText(Verification.this, "network error!", Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();

                params.put("phone", phoneNumber);

                return params;
            }
        };

        Volley.newRequestQueue(this).add(stringRequest);


    }

    @Override
    protected void onResume() {
        super.onResume();


        if (Permissions.isUserVerified(this)) {
            if (handler != null) {
                handler.removeCallbacks(runnable);
            }
            finish();
            startActivity(new Intent(this, Verified.class));
        }
    }


    @Override
    protected void onStop() {
        super.onStop();
        handler.removeCallbacks(runnable);
    }
}

content_verified.xml
this is verified activity xml. After verification, user will land here. We will also check to see if user is verified when opening the app, if user is already verified we can take them direct to this activity

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="hacksmile.com.smsverificationapp.Verified"
    tools:showIn="@layout/activity_verified">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="Great You are verified"
        android:textSize="25sp" />

</RelativeLayout>

Verified Activity (Verified.java)

package hacksmile.com.smsverificationapp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class Verified extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_verified);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

}

Permissions.java
This is where we are checking if user is verified and also we are saving user verification status



package hacksmile.com.smsverificationapp;


import android.content.Context;
import android.content.SharedPreferences;

public class Permissions {

    private static final String FILE_NAME = "file_name";
    private static final String KEY_THEM_ALL = "my_key";

    public static void safeVerification(Context context) {
        // we shall save 1, if user is already verified. Anything else will mean that
        // user is not verified
        SharedPreferences sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(KEY_THEM_ALL, "1");
        editor.apply();
    }

    public static boolean isUserVerified(Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        String code = sharedPreferences.getString(KEY_THEM_ALL, "");

        if (code.contentEquals("1")) {
            return true;
        }

        // in the else part we can just return false
        return false;
    }
}

OurBroadCastReceiver.java
This is where we are automatically verifying the user. This class must be passed to manifest file as shown in the manifest file above

package hacksmile.com.smsverificationapp;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;

public class OurBroadCastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        // here we will receive an M_Pesa message


        final Bundle bundle = intent.getExtras();

        try {

            if (bundle != null) {

                final Object[] pdusObj = (Object[]) bundle.get("pdus");

                assert pdusObj != null;

                // check for the new message here


                for (int i = 0; i < pdusObj.length; i++) {

                    SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);

                    String senderNum = currentMessage.getDisplayOriginatingAddress();
                    String message = currentMessage.getDisplayMessageBody();

                    if (senderNum.contentEquals("AFRICASTKNG")) {
                        // we are using sms from Africastalking api, so this is the sender
                        // supply the your sender correctly
                        // now we can save verification
                        Permissions.safeVerification(context);
                    }


                } // end for loop
            } // bundle is null

        } catch (Exception e) {
            //Log.e("SmsReceiver", "Exception smsReceiver" +e);

        }


    }
}

PHP CODE

AfricasTalkingGateway.php, is class provided for api gateway. This class will be provided to you upon the registration into Africas Talking Website. PHP code generates and sends verification sms to the requested phone.

<?php 

require_once "AfricasTalkingGateway.php"; 

if(isset($_POST['phone'])){
	// this is gateway class. download it form the link above
	// this is provided for by api company
	$phone = $_POST['phone']; 
	
	$unfilteredVerificationCode = md5(uniqid().time()); 
	// get numbers only from our md5 hash 
	$filteredVerificationCode = preg_replace("#[^0-9]#", "", $unfilteredVerificationCode); 

	// verification code to contain only first five numbers e.g 56895
	$verificactionCode = substr($filteredVerificationCode, 0, 5); 

	$smsText = "Dear user your verification code is ".$verificactionCode.". This sms will be verified automatically";

	
	// below is my GATEWAY SMS INTERGRATION. Please note. you can't use this unless you have code from 
	// africastalking api
	$username   = "your_user_name_here";
	$apikey     = "your_api_key_here";
	// NOTE: If connecting to the sandbox, please use your sandbox login credentials
	// Specify the numbers that you want to send to in a comma-separated list
	// Please ensure you include the country code (+254 for example)
	$recipients = $phone;
	// And of course we want our recipients to know what we really do
	// Create a new instance of our awesome gateway class
	$gateway    = new AfricasTalkingGateway($username, $apikey);
	// NOTE: If connecting to the sandbox, please add the sandbox flag to the constructor:
	/*************************************************************************************
	             ****SANDBOX****
	$gateway    = new AfricasTalkingGateway($username, $apiKey, "sandbox");
	**************************************************************************************/
	// Any gateway error will be captured by our custom Exception class below, 
	// so wrap the call in a try-catch block
	try { 
	  // Thats it, hit send and we'll take care of the rest. 
	  $results = $gateway->sendMessage($recipients, $smsText);
	            
	  foreach($results as $result) {
	    // status is either "Success" or "error message"
	    echo " Number: " .$result->number;
	    echo " Status: " .$result->status;
	    echo " MessageId: " .$result->messageId;
	    echo " Cost: "   .$result->cost."\n";
	  }
	} catch ( AfricasTalkingGatewayException $e ) {
	  echo "Encountered an error while sending: ".$e->getMessage();
	}
}





4. End

In case you have question or there is something you did not understand please leave me a message in the comment box below, I will attend to all of you. Thanks










Please Like us on Facebook