OTP (token) should be automatically read from the message

135,015

Solution 1

You can try using a simple library like

After installing via gradle and adding permissions initiate SmsVerifyCatcher in method like onCreate activity:

    smsVerifyCatcher = new SmsVerifyCatcher(this, new OnSmsCatchListener<String>() {
    @Override
    public void onSmsCatch(String message) {
        String code = parseCode(message);//Parse verification code
        etCode.setText(code);//set code in edit text
        //then you can send verification code to server
    }
});

Also, override activity lifecicle methods:

  @Override
protected void onStart() {
    super.onStart();
    smsVerifyCatcher.onStart();
}

@Override
protected void onStop() {
    super.onStop();
    smsVerifyCatcher.onStop();
}

/**
 * need for Android 6 real time permissions
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    smsVerifyCatcher.onRequestPermissionsResult(requestCode, permissions, grantResults);
}


public String parseCode(String message) {
    Pattern p = Pattern.compile("\\b\\d{4}\\b");
    Matcher m = p.matcher(message);
    String code = "";
    while (m.find()) {
        code = m.group(0);
    }
    return code;
}

Solution 2

I implemented something of that such. But, here is what I did when the message comes in, I retrieve only the six digit code, bundle it in an intent and send it to the activity or fragment needing it and verifies the code. The example shows you the way to get the sms already. Look at the code below for illustration on how to send using LocalBrodcastManager and if your message contains more texts E.g Greetings, standardize it to help you better. E.g "Your verification code is: 84HG73" you can create a regex pattern like this ([0-9]){2}([A-Z]){2}([0-9]){2} which means two ints, two [capital] letters and two ints. Good Luck!

After discarding all un needed info from the message

 Intent intent = new Intent("AddedItem");
 intent.putExtra("items", code);
 LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 

And the Fragment/Activity receiving it

@Override
public void onResume() {
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter("AddedItem"));
    super.onResume();
}

@Override
public void onPause() {
    super.onDestroy();
    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
}

And the code meant to handle the payload you collected

 private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction()) {
            final String message = intent.getStringExtra("message");
            //Do whatever you want with the code here
        }
    }
};

Does that help a little bit. I did it better by using Callbacks

Share:
135,015
user1903022
Author by

user1903022

Updated on August 17, 2021

Comments

  • user1903022
    user1903022 almost 3 years

    I am working on an Android App, in which the server sends an OTP and the user needs to enter this OTP in the App, to SignUp for my App. What I want is, that my App should be able to automatically read the OTP sent by the server. How can I achieve this? Any help or guidance in this regard would be highly appreciated.

  • galdin
    galdin over 8 years
    shouldn't you be overriding onPause() instead of onDestroy()?
  • Tonespy
    Tonespy over 8 years
    It depends on how you want to use it. If the Fragment or Activity is always active, then leave it in onPause but in my case whereby I need it just once, I can drop it in onPause or onDestroy since both would be called anyway
  • galdin
    galdin over 8 years
    I'm sorry I wasn't clear enough. The call to onDestroy() is not guaranteed. Should be using onStop() or onPause() depending on context. Right?
  • TharakaNirmana
    TharakaNirmana over 7 years
    probably the best solution, and easy too.
  • Christopher M.
    Christopher M. over 6 years
    Best solution ever. Thank you so much
  • Admin
    Admin about 6 years
    what is parseCode here
  • Rupam Das
    Rupam Das about 6 years
    @angelina Here you are getting the complete message text in onSmsCatch. So you have to parse the message text to get the OTP.
  • Rahul Kushwaha
    Rahul Kushwaha over 5 years
    But This is not workinhg now because Google has diasble to use READ SMS and ReCIVE SMS. This isnot working on my side'
  • Hitesh Kushwah
    Hitesh Kushwah over 5 years
    it takes SMS PERMISSION Without sms permission it not work
  • shaktisinghmoyal
    shaktisinghmoyal over 4 years
    This solution is now deprecated by google now. You should use the SMS Retriever API. It require some changes in both mobile side and server side . You can find detailed instructions here: developers.google.com/identity/sms-retriever/overview