Friday 25 May 2012

Broadcast Receiver: Two ways to implement part-1

I got confused while learning about the broadcast receiver after browsing around the web. Some people register it inside activities while other register it in manifest. The purpose of this tutorial is to explain both ways and the use-cases when to use which implementation.

Broadcast receiver is an application component like activity and service. Its sole aim is to listen for broadcast for which it is registered (through intent-filters). Broadcast receiver can receive broadcast from android system, other applications and from inside the application. Read more about broadcast receivers at developer.android.

We can register receiver in manifest.xml or inside an Activity. We should use define and register broadcast receiver inside activity if we want perform action related to activity (e.g updating UI). We should define it in standalone class otherwise.

No matter what your use-case is, Lets see how to implement these two ways. Lets say we have BroadcastExampleActivity and a receiver inside it called Myreceiver:



public class BroadcastExampleActivity extends Activity {
    /** Called when the activity is first created. */
    private Myreceiver reMyreceive;
    private IntentFilter filter;
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        unregisterReceiver(reMyreceive);
     }
     @Override
     protected void onResume() {
        // TODO Auto-generated method stub
         super.onResume();
        
          registerReceiver(reMyreceive, filter);
     } 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Log.d("sohail", "onCreate called");
       
        reMyreceive=new Myreceiver();
       
       //typo mistake 
       //Edited after pointing out by a reader, thanks 
       // IntentFilter filter=new IntentFilter("sohail.aziz");

        filter=new IntentFilter("sohail.aziz");         
       
        Intent i= new Intent(this,MyIntentService.class);
        Log.d("sohail", "starting MyIntentservice");
        startService(i);
    }
    
    public class Myreceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            
            Log.d("sohail", "MyReceiver: broadcast received");
        }
        
    }
} 



Note that while implementing inside activity, receiver should be registered in OnResume() and unregistered in OnPause() in order to "cut down unnecessary system overhead- developer.android". [Otherwise your receiver will continue running even when activity get paused! check example in updated source]. Intenfilter("sohail.aziz") is the action name for which this receiver is listening. Broadcast sender must set the action name for intended recipient. Lets define MyIntentservice which will send the broadcast.



public class MyIntentService extends IntentService{

    public MyIntentService() {
        super("MyIntentService");
        // TODO Auto-generated constructor stub
        
        Log.d("sohail","Myintentservice constructor");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        // TODO Auto-generated method stub
        
        Log.d("sohail", "onHandle intent called");
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        Intent in= new Intent();
        in.setAction("sohail.aziz");
        Log.d("sohail", "onHandleIntent: sending broadcast");
        sendBroadcast(in);
     
    
    }

}



Notice that we are sending broadcast here with action "sohail.aziz", this is the same action name for which we set intentfilter in our broadcast receiver. Now when broadcast is sent by sendBroadcast, Myreceiver onReceive will be called and intent will be passed to it. You can pass anything via intent. This way we don't need to register receiver inside manifest.xml as it has become a sub component of the activity.

Second method: Broadcast Receiver: Two ways to implement part-2


13 comments:

  1. thnks. this really helped me a lot :)

    ReplyDelete
  2. Your variable private IntentFilter filter; is never initialized and your statement registerReceiver(reMyreceive, filter); is equivalent to registerReceiver(reMyreceive, null);. Can you guess why? :)

    ReplyDelete
    Replies
    1. Yes got it, thanks for pointing out, (left in proof reading).

      Delete
  3. I'm working with your solution but i register with android.intent.action.DATA_SMS_RECEIVED.
    This is my code: IntentFilter mFilter = new IntentFilter(
    "android.intent.action.DATA_SMS_RECEIVED");
    mFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    mFilter.addDataAuthority("localhost", "xxxxx");
    mFilter.addDataScheme("sms");
    if (smsReceiver == null)
    smsReceiver = new SmsReceiverBroadcast();
    context.registerReceiver(smsReceiver, mFilter);
    It works, but sometime i can't get message, It's not stable. I don't know the reason.

    ReplyDelete
  4. Thanks for your help!

    ReplyDelete
  5. It is of great help. Thanks!

    ReplyDelete
  6. Hi--
    Can we register BroadCastReceiver inside another broadCastReceiver ?
    Might sound stupid but ending up in a situation like this....scenario is
    On PhoneStartup I would like to register SMSService. I do not want to make it traditional way of putting in AndroidManifest.xml as I will be exposing interface to initialize my app which in turn starts up SMSBroadCastReceiver using code below

    Log.d(TAG,"Registering SMS BroadCast receiver");
    SMSReceiver mSMSreceiver = new SMSReceiver(nemesisManager);
    IntentFilter mIntentFilter = new IntentFilter();
    mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
    context.registerReceiver(mSMSreceiver, mIntentFilter);
    Log.d(TAG,"Registered SMS BroadCast receiver");

    Any help suggestion please...

    Cheers,
    Prashanth

    ReplyDelete
  7. hello, thanks for the tutorial.
    after this line:
            filter=new IntentFilter("sohail.aziz");        
    you do not use use " filter" - where is it used?
    thanks
    anna


    ReplyDelete
    Replies
    1. its used in onResume while registering the receiver.

      Delete
  8. Thanks for making this tutorial, its totally helpful.

    ReplyDelete
  9. Thank you, flawless!

    ReplyDelete
  10. Fix the link to your part 2. It is suppose to be
    http://sohailaziz05.blogspot.com/2012/05/broadcast-receiver-two-ways-to_28.html
    NOT
    http://www.sohailaziz.com/2012/05/broadcast-receiver-two-ways-to_28.html

    ReplyDelete