Coding Tutorials

Automatically Reading SMS To Verify OTP

Vidhi Markhedkar
Automatically Reading SMS To Verify OTP

In the digital age, security and convenience often go hand-in-hand, particularly in the realm of online transactions. One of the most significant advancements in this area is the use of One-Time Passwords (OTPs) for verification.

A critical aspect of this process is the ability to automatically read SMS to verify OTPs. This functionality not only streamlines user verification processes but also adds an extra layer of security to mobile applications.

Instead of using third party libraries to auto fetch OTP from SMS Inbox ,we can easily do this using Broadcast Receiver. Broadcast receiver allows you to send or receive application events.

Steps To Automatically Reading SMS To Verify OTP

Step1: Open app > res > drawable 

Create a new resource file 

Add the following xml code to create a custom background

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#dcdcdc"/>
</shape>

Step 2: Create a vector Image use any image clip art.

Open drawable > new > vector Asset

Step 3:  Create Layout File for OTP Verification

<?xml version="1.0" encoding="utf-8"?>
<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_width="match_parent"
    	android:layout_height="match_parent"
    	android:gravity="center"
    	android:orientation="vertical"
    	app:layout_constraintBottom_toBottomOf="parent"
    	app:layout_constraintEnd_toEndOf="parent"
    	app:layout_constraintStart_toStartOf="parent"
    	app:layout_constraintTop_toTopOf="parent">

    	<ImageView
        	android:layout_width="250dp"
        	android:layout_height="250dp"
        	android:layout_gravity="center"
        	android:background="@drawable/textsms">

    	</ImageView>

    	<LinearLayout
        	android:layout_width="match_parent"
    	    android:layout_height="60dp"
        	android:layout_marginLeft="10dp"
        	android:layout_marginTop="20dp"
        	android:background="@drawable/edittext_background">

        	<EditText
            	android:id="@+id/edittext"
            	android:layout_width="match_parent"
            	android:layout_height="match_parent"
            	android:background="@android:color/transparent"
            	android:gravity="center"
            	android:hint="OTP HERE"
            	android:inputType="number" />
    	</LinearLayout>

    	<Button
        	android:layout_width="wrap_content"
        	android:layout_height="wrap_content"
        	android:layout_gravity="center"
        	android:layout_marginTop="20dp"
        	android:background="#3F51B5"
        	android:gravity="center"
        	android:text="Verify"
        	android:textColor="#FFF" />

	</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Step 4: Create a new java class

java < com.example.smsotp < new< java class

Create single Broadcast Receiver i.e SmsReceive  to listen to our incoming SMS

eg: sms received is Your OTP is : 4587, Then in above code we have split the complete message string in to 2 parts using “:” this special symbol.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.widget.EditText;

import androidx.annotation.RequiresApi;

public class OTP_Receiver extends BroadcastReceiver {
   private  static EditText editText;
   public void setEditText(EditText editText)
   {
       OTP_Receiver.editText=editText;
   }
   // OnReceive will keep trace when sms is been received in mobile
   @RequiresApi(api = Build.VERSION_CODES.KITKAT)
   @Override
   public void onReceive(Context context, Intent intent) {
       //message will be holding complete sms that is received
       SmsMessage[] messages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
       for(SmsMessage sms : messages)
       {
           String msg = sms.getMessageBody();
           // here we are splitting the sms using " : " symbol
           String otp = msg.split(": ")[1];
           editText.setText(otp);
       }
   }
}

Step 5: MainActivity.java 

we send request to user to access sms and access the otp if permission is granted

import android.Manifest;
       import android.content.pm.PackageManager;
       import android.os.Bundle;
       import android.widget.EditText;
       import androidx.annotation.Nullable;
       import androidx.appcompat.app.AppCompatActivity;
       import androidx.core.app.ActivityCompat;
       import androidx.core.content.ContextCompat;
public class MainActivity extends AppCompatActivity {
   EditText otpnumber;

   @Override
   public void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       //we ask user permission to auto read sms
       requestsmspermission();
       otpnumber = (EditText) findViewById(R.id.edittext);
       new OTP_Receiver().setEditText(otpnumber);
   }

   private void requestsmspermission() {
       String smspermission = Manifest.permission.RECEIVE_SMS;
       int grant = ContextCompat.checkSelfPermission(this, smspermission);
       // to check if read SMS permission is granted or not
       if (grant != PackageManager.PERMISSION_GRANTED) {
           String[] permission_list = new String[1];
           permission_list[0] = smspermission;
           ActivityCompat.requestPermissions(this, permission_list, 1);
       }
   }
}

Steps 6: Add Listener i.e broadcast receiver in android manifest file under<application>tag and also add user-permission inside <manifest>

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

//add this code to ask permissions to access sms
   <uses-permission android:name="android.permission.RECEIVE_SMS"/>
   <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
   <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
   <uses-permission android:name="android.permission.WRITE_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/Theme.OTPReader">
//add the following receiver code
       <receiver android:name=".OTP_Receiver">
           <intent-filter>
               <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
           </intent-filter>
       </receiver>
       <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>
</manifest>

Alternative Way: Using SMS Retriever API

Google’s SMS Retriever API is an efficient way to read SMS messages for OTP without requiring additional permissions. To use this API, follow these steps:

  1. Generate an App Hash: This unique hash is used to identify your app and should be included in your OTP message.
  2. Receive the OTP Message: Configure your app to listen for an incoming SMS that contains the OTP and your app hash.
  3. Extract the OTP: Once the SMS is received, extract the OTP from the message automatically.

Best Practices and Security Considerations

  • Privacy Compliance: Always adhere to privacy laws and regulations when accessing and handling SMS messages.
  • Timeout for OTP: Implement a timeout for the OTP validity to prevent unauthorized use.
  • Rate Limiting: To avoid abuse, limit the number of OTP requests a user can make within a certain time frame.

Conclusion

Automatically reading SMS to verify OTP in Android Studio is a game-changer in terms of security and user experience. By following the steps outlined above, developers can effectively implement this feature, ensuring both convenience and enhanced security for their app users.

Remember to keep user privacy and security at the forefront of your implementation strategy. With these tools and techniques, your Android app will not only be more secure but also provide a smoother and more user-friendly experience.