1

Folks! I'm trying to implement BroadcastReceiver for listening to incoming Message using SMSRetrieverAPI.

I'm getting messages in Broadcast's onReceive method but after that, I have to pass that Message String in activity without restarting it, So I have implemented interface.

I have tried below code but, it throws NullPointerException for mOTPReceiveListener. Something didn't work perfectly so please correct me.

SMSBroadcastReceiver is like below

public class SMSBroadcastReceiver extends BroadcastReceiver {

OTPReceiveListener mOTPReceiveListener = null;

public void InitOTPReceiveListener(OTPReceiveListener otpreceivelistener){

    this.mOTPReceiveListener = otpreceivelistener;
}

@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);

        switch(status.getStatusCode()) {
            case CommonStatusCodes.SUCCESS:
                // Get SMS message contents
                String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                Log.e("VERIFY","Full Message : "+message);

                if (mOTPReceiveListener != null) {
                    String[] temp = message.split("-");
                    String[] msg = temp[1].split(" ");
                    message = msg[0];

                    Log.e("VERIFY","message : "+message);
                    mOTPReceiveListener.onOTPReceived(message);

                }

                break;
            case CommonStatusCodes.TIMEOUT:
                // Waiting for SMS timed out (5 minutes)
                mOTPReceiveListener.onOTPTimeOut();
                break;
        }
    }
}

public interface OTPReceiveListener {
    void onOTPReceived(String otp);

    void onOTPTimeOut();
}

}

and the activity code

public class VerificationActivity extends BaseActivity implements SMSBroadcastReceiver.OTPReceiveListener
{
    Context mContext;
    Button btn_verify_submit;
    TextView text_resend_otp;

    private String TAG = "VERIFY";

    private String PHONE = null;

    private SmsRetrieverClient mSmsRetrieverClient;
    private SMSBroadcastReceiver mSMSBroadcastReceiver;
    SMSBroadcastReceiver.OTPReceiveListener mOTPReceiveListener;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_verification);

        initView();
        setClickListener();

        PHONE = getIntent().getStringExtra("phone");
        Log.e(TAG,"phone : "+PHONE);

        mSmsRetrieverClient = SmsRetriever.getClient(this);
        startVerify();

        mOTPReceiveListener = this;
        mSMSBroadcastReceiver = new SMSBroadcastReceiver();
        mSMSBroadcastReceiver.InitOTPReceiveListener(this);

    }

    private void initView()
    {
        layout_verification_main = findViewById(R.id.layout_verification_main);
        overrideFonts(layout_verification_main,VerificationActivity.this);

        edt_verify_code = findViewById(R.id.edt_verify_code);

        btn_verify_submit = findViewById(R.id.btn_verify_submit);

        text_resend_otp = findViewById(R.id.text_resend_otp);
    }

    private void setClickListener()
    {
        btn_verify_submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //Call OTP Match API

            }
        });

        text_resend_otp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Call Resend OTP API 
            }
        });
    }




    private void startVerify() {
        Task<Void> task = mSmsRetrieverClient.startSmsRetriever();
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {

                Log.e(TAG, "SmsRetrievalResult start onSuccess.");


            }
        });

        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(TAG, "SmsRetrievalResult start failed.", e);
            }
        });

    }

    @Override
    public void onOTPReceived(String otp) {
        edt_verify_code.setText("" + otp);
        Toast.makeText(mContext, "Message OTP :  " + otp, Toast.LENGTH_SHORT).show();
        Log.e("VERIFY","otp in activity : "+otp);
    }

    @Override
    public void onOTPTimeOut() {

    }
}

and I have registered in Manifest like this

<receiver android:name=".broadcast.SMSBroadcastReceiver" android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
    </intent-filter>
</receiver>

Am I missing something?

Android
  • 1,420
  • 4
  • 13
  • 23
Hardik Kubavat
  • 251
  • 3
  • 23
  • 1
    you are calling this `InitOTPReceiveListener()` in your onCreate() of activity? that seems wrong – Anmol Jan 05 '19 at 05:32

2 Answers2

0

The SMSBroadcastReceiver instance created from the definition in your manifest is NOT the same one you created in VerificationActivity.onCreate().

You can register the broadcast receiver from your activity using Context.registerReceiver().

xizzhu
  • 895
  • 6
  • 9
0

To contact between activity and receiver what you are try is wrong as your listener is dependent on activities onCreate() i.e on lifecycle of Activity. So to solve this you need to follow below step's:

Solution

  1. Be sure that activity is alive by starting the activity from your receiver (startActitvity() using intent ) again. check this thread if you don't want to restart the activity again and want to be sure that activity is on screen.
  2. Send a broadcast from your receiver to activity read this thread. No need of listener as activity can directly listen to message

you can combine both solution's for you own use case it will work.

Anmol
  • 8,110
  • 9
  • 38
  • 63