【问题标题】:Communication between BroadcastReceiver and Activity using interfaceBroadcastReceiver和Activity之间使用接口通信
【发布时间】:2019-05-31 15:11:00
【问题描述】:

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

我在 Broadcast 的 onReceive 方法中收到消息,但在那之后,我必须在活动中传递该消息字符串而不重新启动它,所以我已经实现了接口。

我尝试过下面的代码,但是它会为 mOTPReceiveListener 抛出 NullPointerException。有什么地方不完美,所以请纠正我。

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>

我错过了什么吗?

【问题讨论】:

  • 您在 onCreate() 活动中调用此InitOTPReceiveListener()?这似乎是错误的

标签: android interface broadcastreceiver


【解决方案1】:

在活动和接收者之间联系你的尝试是错误的,因为你的听众依赖于活动onCreate(),即活动的生命周期。 因此,要解决此问题,您需要按照以下步骤操作:

解决方案

  1. 通过再次从接收器启动活动(使用 intent 的 startActitvity())来确保活动处于活动状态。如果您不想再次重新启动活动并希望确保该活动在屏幕上,请检查此thread
  2. 从您的接收器向活动发送广播,阅读此thread不需要监听器 因为activity可以直接监听消息

您可以根据自己的用例将这两种解决方案结合起来使用。

【讨论】:

    【解决方案2】:

    根据清单中的定义创建的 SMSBroadcastReceiver 实例与您在 VerificationActivity.onCreate() 中创建的实例不同。

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

    【讨论】:

      猜你喜欢
      • 2015-03-20
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多