使用接口在BroadcastReceiver和Activity之间进行通信

时间:2019-01-05 05:26:37

标签: android interface broadcastreceiver

伙计! 我正在尝试实现BroadcastReceiver来使用SMSRetrieverAPI监听传入的消息。

我正在通过Broadcast的onReceive方法获取消息,但此后,我必须在活动中传递该消息字符串,而无需重新启动它,因此,我已经实现了接口。

我尝试下面的代码,但是它为NullPointerException抛出了mOTPReceiveListener。某些功能无法正常运行,请纠正我。

SMSBroadcastReceiver如下所示

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();
}

}

和活动代码

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() {

    }
}

我已经这样在Manifest中注册

<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>

我想念什么吗?

2 个答案:

答案 0 :(得分:0)

根据清单中的定义创建的FragmentStatePagerAdapter实例与您在SMSBroadcastReceiver中创建的实例不同。

您可以使用Context.registerReceiver()从您的活动中注册广播接收器。

答案 1 :(得分:0)

要在活动和接收者之间进行联系,您尝试做的事情是错误的,因为您的听众取决于活动onCreate(),即活动的生命周期。 因此,要解决此问题,您需要执行以下步骤:

解决方案

  1. 通过再次从接收者(使用intent的startActitvity())启动活动,确保该活动仍然有效。如果您不想再次重新启动活动并希望确保活动显示在屏幕上,请选中此thread
  2. 从接收方发送广播以进行活动,请阅读此thread不需要收听者,因为活动可以直接收听消息

您可以结合使用两种解决方案以适合您自己的用例。