user8430 user8430 - 3 months ago 64
Android Question

How to pass data from BroadcastReceiver to Activity without in onCreate()

I have a serious issue about passing data from

BroadcastReceiver
to an
Activity
. Let see my issue carefully. I have a class
PhoneStateReceiver extends BroadcastReceiver
that used to received an incoming phone.

public class PhoneStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
System.out.println("Receiver start");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){

}
}
catch (Exception e){
e.printStackTrace();
}
}
}


The incoming phone will be sent to an
Activity
, called
ReceiverActivity
. The
ReceiverActivity
receives the incoming phone and sends it to a server via a socket connection. The socket connection is initialized in the
onCreate
function. I googled and found server way to pass the data from
BroadcastReceiver
to an
Activity
. The common way is that send data via
putExtra
function and call
startActivity
. However, the way will call the
onCreate
again and then connect the socket, draw the UI again. Thus, it is not helpful in my case.

In my goal, If the phone receives an incoming call, it will send the incoming call to the
ReceiverActivity
. The
ReceiverActivity
receives the message and calls the send function. Which is the best way to do it? Thank you

The common way to pass data from a
BroadcastReceiver
to a
ReceiverActivity
that I used as follows

In PhoneStateReceiver class :

Intent intent_phonenum = new Intent(context, ReceiverActivity.class);
intent_phonenum.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent_phonenum.putExtra("phone_num", incomingNumber);
context.startActivity(intent_phonenum);


In ReceiverActivity class :

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect_socket();
Intent intent = getIntent();
phone_num = intent.getStringExtra("phone_num");
send(phone_num);
}

Answer

There is a very simple design pattern you can use here to ease communication between your classes and also decouple your code: publisher/subscriber. My favorite library for this is EventBus:

First, add to your build.gradle file:

compile 'org.greenrobot:eventbus:3.0.0'

Then, create a simple POJO - Plain Old Java Object like this:

public class OnReceiverEvent{
   private String phoneNumber;

   public OnReceiverEvent(String phone){
      this.phoneNumber = phone;
   }

   public String getPhoneNumber(){
      return phoneNumber;
   }
}

Next, by making your Receiver class a publisher, and your Activity a subscriber, you should be able to easily pass the information to your activity like this:

//inside your PhoneStateReceiver class when you want to pass info

EventBus.getDefault().post(new OnReceiverEvent(phoneNumber));

Next, inside your activity, simply do this:

//onStart
@Override
public void onStart(){
   super.onStart();
   EventBus.getDefault().register(this);
}

//onStop
@Override
public void onStop(){
   super.onStop();

   EventBus.getDefault().unregister(this);
}

Finally, handle the posted data i.e phoneNumber value:

@Subscribe
public void onPhoneNumberReceived(OnReceiverEvent event){
   //get the phone number value here and do something with it

   String phoneNumber = event.getPhoneNumber();

   //display or something?
}

This is the easiest way to pass the data from your receiver to your activity without having to worry about starting the activity over and over!

I hope this helps and good luck!