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>