androidandroid-sms

I tried to read OTP from received SMS with SmsRetrieverClient but broadcast receiver not calling


I have tried to get sms using SmsRetrieverClient through its broadcast receiver, what actually problem is when SMS comes onReceive never calls to process it further but later on after 5 mins it calls receiver's timeout method.

Actually I tried library to get SMS and its working fine but asking for SMS read permission which unfortunately will face Google policy issue at the time of uploading app on playstore.

Below is my code.

Below is the SmsRetrieverClient method in my Activity:

 private void startSMSListener() {

    SmsRetrieverClient smsRetrieverClient = SmsRetriever.getClient(this);
    Task<Void> retriever = smsRetrieverClient.startSmsRetriever();
    retriever.addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            SMSBroadcastReceiver.OTPListener otpListener = new SMSBroadcastReceiver.OTPListener() {
                @Override
                public void onOTPReceived(String otpData) {
                    inputOTP.setText(otpData);
                }

                @Override
                public void onOTPTimeOut() {
                    inputOTP.setText("");
                    Toast.makeText(ctx, "TimeOut", Toast.LENGTH_SHORT).show();
                }
            };

            smsBroadcastReceiver.injectOTPListener(otpListener);
            registerReceiver(smsBroadcastReceiver, new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION));
        }
    });

    retriever.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(ctx, "Problem to start listener", Toast.LENGTH_SHORT).show();
        }
    });

}

Below code is of receiving SMS from broadcast receiver:

public class SMSBroadcastReceiver extends BroadcastReceiver {
private OTPListener otpReceiver;

public void injectOTPListener(OTPListener receiver) {
    this.otpReceiver = receiver;
}

@Override
public void onReceive(Context context, Intent intent) {
    if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
        Bundle extras = intent.getExtras();
        Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
        System.out.println("SMS verification code::SMSBroadcastReceiver:0:  "+ status);

        switch (status.getStatusCode()) {

            case CommonStatusCodes.SUCCESS:

                String message = (String)extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                Pattern pattern = Pattern.compile("\\d{4}");
                Matcher matcher = pattern.matcher(message);
                System.out.println("SMS verification code::SMSBroadcastReceiver:1:  "+ message);

                if (matcher.find()) {
                    if (otpReceiver != null){
                        otpReceiver.onOTPReceived(matcher.group(0));
                    }
                }
                break;

            case CommonStatusCodes.TIMEOUT:
                System.out.println("SMS verification code::SMSBroadcastReceiver:2:  TIMEOUT");

                if (otpReceiver != null){
                    otpReceiver.onOTPTimeOut();
                }
                break;
        }
    }
}


public interface OTPListener {

    void onOTPReceived(String otp);

    void onOTPTimeOut();
}
}

And in manifest:

     <receiver android:name=".SMSBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action 

 android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>

        </intent-filter>
        </receiver>

Solution

  • Big Thanks for contributing your solutions, But I found out the solution after so many attempts the reason why broadcast was not receiving SMS otp is due to 2 reason:

    1) The message should be of 140 bytes as in below link:

    https://developers.google.com/identity/sms-retriever/verify#1_construct_a_verification_message

    2) I found that at the time of developing broadcast I got 2 to 3 broadcast java files which I added in my app for testing the SMS each with different code which I registered in manifest all the SMS broadcast receivers with same action which was meaningless. So lastly removing all the other registered receivers from manifest of same action as "com.google.android.gms.auth.api.phone.SMS_RETRIEVED" and just worked on single broadcast receiver with single declaration in manifest with its action solved my problem.