NAVIGATION - SEARCH

Android - How To Verify OTP Via SMS Or Implement OTP Verification Logic

In almost every app that require users to login or provide phone numbers, there is a need to validate the input phone number. Usually the best way is to send out a code in SMS to the number and then read the SMS messages to query back for verification. This methodology of using SMS to validate the phone number is tried and tested although it is dependent on the phone carrier and sometimes the SMS get delayed which hampers the user experience. But in majority of cases, this type of SMS OTP verification occurs within few seconds.

In this article we will deploy a simple methodology of sending an SMS from the app and then keep reading the SMS messages to validate the OTP. Here we are assuming that you have a simple interface where an EditText is used to input phone number and a button to send the SMS and then read SMS messages to validate the OTP.

public class MainActivity extends Activity
{
	EditText txtPhone;
	Button btnVerify;

	CountDownTimer CDT;

	final String PREFS_FILE = "MySharedPrefs";

	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		txtPhone = (EditText) findViewById(R.id.txtPhone);
		btnVerify = (Button) findViewById(R.id.btnVerify);

		btnVerify.setOnClickListener(new OnClickListener() 
		{
			@Override
			public void onClick(View v) 
			{
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setTitle("Verify Phone);
				builder.setMessage("Do you allow this app to send out an SMS?");

				builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() 
				{
					public void onClick(DialogInterface dialog, int which) 
					{
						String PHONE = txtPhone.getText().toString().trim();
						SimpleDateFormat SDF = new SimpleDateFormat("HHmmss");
						String OTP = "MyOTP" + SDF.format(new Date());

						SharedPreferences writesettings = getSharedPreferences(PREFS_FILE, 0);
						SharedPreferences.Editor editor = writesettings.edit();
						editor.putString("OTP", OTP);
						editor.commit();

						SmsManager SMS = SmsManager.getDefault();
						SMS.sendTextMessage(PHONE, null, OTP, null, null);
						
						CDT = new CountDownTimer(30000, 2000)
						{
							@Override
							public void onTick(long millisUntilFinished) 
							{
								SharedPreferences readsettings = getSharedPreferences(PREFS_FILE, 0);
								String ValidOTP = readsettings.getString("OTP", "");

								Cursor sms = getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI, new String[] {Telephony.Sms.Inbox.BODY}, null , null, null);
								if(sms != null)
								{
									while (sms.moveToNext())
									{
										String body = sms.getString(0);
										if(body.equalsIgnoreCase(ValidOTP))
										{
											Log.d("", "Number verified");
											CDT.cancel();
										}
									}
									sms.close();
								}
							}

							@Override
							public void onFinish() 
							{

							}
						}.start();
					}
				});

				builder.setNegativeButton("No", new DialogInterface.OnClickListener() 
				{
					public void onClick(DialogInterface dialog, int which) 
					{
						dialog.cancel();						
					}
				});

				AlertDialog dialog = builder.create();
				dialog.show();
			}
		});
	}

	@Override
	protected void onPause()
	{
		super.onPause();
		if(CDT != null)
			CDT.cancel();
	}

	@Override
	protected void onDestroy()
	{
		super.onPause();
		if(CDT != null)
			CDT.cancel();
	}
}

The above code takes the phone number as input and on button click shows an alert dialog box for user confirmation. When user verifies, it initiates 2 actions.

First it generates a simple OTP code and sends it to input phone number as SMS and stores it in SharedPreferences for later retreival.

Second it starts a CountDownTimer for 30 seconds, retreives OTP from SharedPreferences, keeps reading SMS inbox for any messages. As soon as it encounters a message having OTP, a success message is logged in LogCat console.

You need to add the following permission in AndroidManifest.xml

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

Add comment