Saturday, 24 September 2011

Android - Registering a Broadcast Receiver

One of the main advantages of Android is the user of intent which extends the reusability and the modularity of the code. Basically an Intent is a message that is broadcast through the system and any program which has registered proper receiver can receive the intent and do something with the data. Most of the times it has an unique identification called "Action" which is a String.

The basic way to receive the intent is using Broadcast receiver. It is a class which only has one method:

public void onReceive (Context context, Intent intent) {}

There are two ways to register a broadcast receiver: dynamically by java code or statically by Manifest file.

1. Dynamical registering
The advantage of dynamical registering is the broadcast can be dynamically unregistered when it doesn't want to handle more intent.
1.1 Register
1. Create an intent filter specifying the "action" of the intent to receive.
2. Instance the object of broadcast receiver
3. Register the broadcast receiver with the intent filter.

For example:
IntentFilter filter = new IntentFilter ("com.jiahaoliuliu.android.intent");
MyBroadcastReceiver myBR = new MyBroadcastReceiver();
registerReceiver(myBR, filter);

1.2 Unregister
There is a unique and simple method to unregister the broadcast receiver:

try {
    context.unregisterReceiver(positionBroadcastReceiver);
} catch (IllegalArgumentException illegalArgumentException) {
    Log.w(LOG_TAG, "Trying to unregister the broadcast when it has not been registered.");

}

2. Static registering
The advantage and the disadvantage of static registering is once a broadcast is registered, whenever an intent is fired, it will receive it, not matter if the application is dead or it hasn't started yet.

To do it, include XML code in the Manifest file specifying the name of the broadcast receiver and the intent filter.

For example:
<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.jiahaoliuliu.android.intent"/>
    </intent-filter>
</receiver>

For more information:
Android developers - Intent and Intent Filters: http://developer.android.com/guide/topics/intents/intents-filters.html

10 comments:

  1. Thank you. One of my users asked me to add a feature requiring BroadcastReceiver. I'd never worked with it before.

    ReplyDelete
  2. You are welcome! I am glad that I am useful.

    ReplyDelete
  3. In my application i built four broadcast receiver
    first to receive sms second to sending sms third to detect out going
    call and last to detect incoming call.........now i want that these
    broadcast receiver running continously after device bootup in the
    background sucessfully.......but i dont find any solution to implement
    this functionality......may be if i aggregate these four broadcast
    receiver functionality in service class and implement new broadcast
    receiver for reboot functionality which execute this service class
    which containing my four broadcast receiver
    functionality ..........may be it work but i dont find any solution
    how to implement broadcastreceiver in service how to add my four
    broadcast receiver functionality in service......please provide me
    some link or logic to implement this functionality thanks in advance!!!

    ReplyDelete
    Replies
    1. Hi Asheesh:
      If you want your broadreceiver to receive a specific intent since device has boot, definitely you should put it in the Android Manifest file.

      If you want to use a server which starts when the device booted, you might check:
      http://stackoverflow.com/questions/5290141/android-broadcastreceiver-on-startup

      Delete
  4. You said dynamically can do the register in class... but in which class i should type the code below..
    IntentFilter filter = new IntentFilter ("com.jiahaoliuliu.android.intent");
    MyBroadcastReceiver myBR = new MyBroadcastReceiver();
    registerReceiver(myBR, filter);

    Please help... i am fresher for android..

    ReplyDelete
    Replies
    1. Hi:
      You should include the code in the activity class where you want to receive the intent.

      As good practice, add it on the onResume method and add the unRegister method in the onPause method.

      Delete
  5. Hi Sir,
    This was very helpful.
    However what if i want to pass parameters to broadcast receiver?

    Something like this,
    IntentFilter filter = new IntentFilter ("com.jiahaoliuliu.android.intent");
    MyBroadcastReceiver myBR = new MyBroadcastReceiver("this is awesome", 007);
    registerReceiver(myBR, filter);

    If i register the receiver statically, i am unable to pass parameters.

    ReplyDelete
  6. What I understand is you want to pass the parameters via method, not via intents.

    Well, BroadCastReceiver is just another class in java. As such class, you could create a constructor with such parameters.

    e.g.:

    private class MyBroadcastReceiver extends BroadcastReceiver {
    private String mParam1:
    private String mParam2:

    public MyBroadcastReceiver(String param1, String param2) {
    this.mParam1 = param1;
    this.mParam2 = param2;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, mParam1 + mParam2, Toast.LENGTH_LONG).show();
    }
    }

    Note the code above has not been runned on an IDE, so there could be some typos.

    Also be aware that if you create a new constructor with parameters, the default constructor, which does not have any parameter, will not be usable at least you create it explicitly. So, with the code above, you cannot use this:

    MyBroadcastReceiver myBR = new MyBroadcastReceiver();

    at least you add the follow code:

    public MyBroadcastReceiver() {};

    ReplyDelete
    Replies
    1. Thank you for the reply sir.
      This is exactly where i am struck with my project.
      I have already created the variables inside the Broadcast receiver class and i am setting them while creating the instance dynamically.
      Now i have a requirement where i have to register the receiver statically and also send parameters to the broadcast receiver class to set these variables. I have both the empty constructor as well as a constructor taking these parameters i want. Hope you got my point.
      Please let me know if you know how to overcome this. And thanks a lot for the reply :)

      Delete
    2. I was talking this question with a college and we think this question does not has sense.

      If you register a broadcast receiver statically, it could be run even when the app is not running, in that case, how could you enter a variable to the constructor which as its name indicates, it varies the values and it could be different over time.

      If there is any way to pass a variable to a static registered broadcast receiver, it should be done based on the intent that it receives, not via constructor.

      But if what to want do have is that when the broadcast receiver starts, it already has some variable with constant data, what you could do is override the empty constructor with some values, or use static final variable to make them as constant.

      Maybe you should check the structure of your code and ask yourself why do you need a static registered broadcast receiver to receive parameter instead of a dynamic registered broadcast receiver.

      If you post your code or send it to me, I will try to take a look on it.

      Delete