Read SMS automatically to verify OTP

Reading incoming SMS messages for verification (OTP) - Android


Nowadays, Applications usually use SMS texts for authentication purposes, like OTP (One-Time-Passwords), where a message is sent by the service provider and it is automatically read by the application, verifying it. This flow helps user to save a lot of apps by switching from the application to the messenger app and then entering the authentication text to app again.

In this article, We will learn how to read incoming SMS automatically.

We will need 3 classes to perform to achieve our goal. That will be a Broadcast Receiver, a listener, and an Activity.


  • SmsReceiver.java: This is a broadcast receiver that is called when SMS is received.
  • SmsListener.java: This would be our listener interface that will be passed on to our receiver.
  • MainActivity.java: Our calling code where all the action happens.

Implementation

The first thing we should do is declare permissions and intent-filter in AndroidManifest.xml file.

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

<receiver android:name=".SmsReceiver">
    <intent-filter>
       <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver> 
This ensures that this broadcast listener sends the broadcast with SMS data whenever an SMS is received.

Create a simple interface SmsListener.java as follows
public interface SmsListener {
   public void messageReceived(String messageText);
}

Now we will move to the BroadcastReceiver class to implement our core logic.
      
public class SmsReceiver extends BroadcastReceiver {
    private static SmsListener mListener;

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle data  = intent.getExtras();
        Object[] pdus = (Object[]) data.get("pdus");

        for(int i=0;i<pdus.length;i++){
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);

            String sender = smsMessage.getDisplayOriginatingAddress();
            //You must check here if the sender is your provider and not another one with same text.

            String messageBody = smsMessage.getMessageBody();

            //Pass on the text to our listener.
            mListener.messageReceived(messageBody);
        }
    }

    public static void bindListener(SmsListener listener) {
        mListener = listener;
    }
}

Let's see what goes on behind the covers here, the intent contains PDU (Protocol Data Unit) objects, which is a protocol for the transfer of SMS messages in telecoms. We obtain an array of these messages that were sent to our receiver by the system. 

Iterating all these, we create a SmsMessage object using createFromPdu() a method as shown. smsMessage.getDisplayOriginatingAddress() gives us the sender's number. smsMessage.getMessageBody() gives us the message text. Note that we have called mListener.messageReceived() here as a callback when the message is received. 

We are now ready with our core classes, let's implement this.
    public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SmsReceiver.bindListener(new SmsListener() {
            @Override
            public void messageReceived(String messageText) {
                 Log.d("Text",messageText);
                 Toast.makeText(MainActivity.this,"Message: "+messageText,Toast.LENGTH_LONG).show();
            }
        });
    }
}

This is our calling code, it just binds the listener to our receiver by calling SmsReceiver.bindListener() method and a custom implementation telling what should be done when a message is received, this is the same method that is called in our BroadcastReceiver. 

Thats it! Now run your project/app and test the desired result.

Thanks for reading this article. Hope you would have liked it!. Please share and subscribe to my blog to support.

Pragnesh Ghoda

A forward-thinking developer offering more than 8 years of experience building, integrating, and supporting android applications for mobile and tablet devices on the Android platform. Talks about #kotlin and #android

1 Comments

Please let us know about any concerns or query.

  1. Works fine while the app is running. Throws error when the app is closed. mListener.messageReceived(messageBody); throws Null object reference. Please help me

    ReplyDelete
Previous Post Next Post

Contact Form