In Android stack there are many classes which are under utilized. Recently at Truiton I came across another one, and thought of advertising it by Android sendOrderedBroadcast Example with Priority tutorial. Android sendOrderedBroadcast falls in Ordered Broadcasts category of Android broadcasts, which are defined in Context class.
Broadly speaking Android has two types of broadcasts :
- Normal Broadcasts: Under this category broadcasts are sent in an asynchronous fashion i.e. broadcast is received by all the receivers in an asynchronous manner. It has two types:
- * sendBroadcast – It is explained in Android Force Close Application : Session Timeout tutorial.
- * LocalBroadcastManager – This class is used to send local broadcasts i.e. within the app.
- Ordered Broadcasts: This category is the focus category for this Android sendOrderedBroadcast Example with Priority tutorial. Ordered Broadcast is the type of broadcast which is sent in a synchronous manner i.e. one by one to each listener.
Android sendOrderedBroadcast method falls in Context class of Android, the purpose of this method is to broadcast to listening receivers in a serialized manner and receive the result back to the calling activity. I was looking for something like Android sendOrderedBroadcast long back but wasn’t able to find it. Another key advantage of sendOrderedBroadcast is that we can set the priority of BroadcastReceiver. This way all the BroadcastReceivers listening to that specific broadcast will receive that specific broadcast in an ordered manner. Now since we are receiving broadcasts in an ordered way, there might exist a case, when you wish to interrupt the flow of receivers, guess what even this can be done, by abortBroadcast().
To explain the concept of Android sendOrderedBroadcast, I’ll be defining three classes out of which two would be purely BroadcastReceivers. Lets start Android sendOrderedBroadcast example with SendOrderedBroadcastActivity below:
package com.truiton.sendorderedbroadcast; import android.os.Bundle; import android.annotation.SuppressLint; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; import android.view.Menu; public class SendOrderedBroadcastActivity extends Activity { private static String Log_Tag = "SendOrderedBroadcastActivity"; private static String Action = "com.truiton.OrderedBroadcast"; private static String Extras = "Breadcrumb"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.send_ordered_broadcast); IntentFilter filter = new IntentFilter(Action); registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); String trail = results.getString(Extras); results.putString(Extras, trail + "->" + Log_Tag); Log.i(Log_Tag, "Same Class Receiver"); } }, filter); Intent intent = new Intent(Action); sendOrderedBroadcast(intent, null, new BroadcastReceiver() { @SuppressLint("NewApi") @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); Log.i(Log_Tag, "Final Result Receiver = " + results.getString(Extras, "nil")); } }, null, Activity.RESULT_OK, null, null); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.send_ordered_broadcast, menu); return true; } }
Lets have a closer look at the class above, to send an ordered broadcast, at-least we need an Intent with an action. Now since we are using Android sendOrderedBroadcast, I declared a BroadcastReceiver inside the sendOrderedBroadcast method. This receiver would be used to capture the final result after all the BroadcastReceivers are executed.
In the class above I have also registered a receiver. This receiver would be executed just before the final result receiver as priority is not defined for this receiver. In this Android sendOrderedBroadcast example with priority I would be registering two more receivers with priorities in separate classes. But before doing that lets have a look at the manifest file for this app.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.truiton.sendorderedbroadcast" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.truiton.sendorderedbroadcast.SendOrderedBroadcastActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".TruitonReceiver" > <intent-filter android:priority="1" > <action android:name="com.truiton.OrderedBroadcast" /> </intent-filter> </receiver> <receiver android:name=".TruitonReceiverTwo" > <intent-filter android:priority="2" > <action android:name="com.truiton.OrderedBroadcast" /> </intent-filter> </receiver> </application> </manifest>
Have a look at the Manifest above, in this Manifest two receivers have been declared – TruitonReceiver, and TruitonReceiverTwo. These BroadcastReceivers are defined in separate classes and they listen to com.truiton.OrderedBroadcast action. Lets have a closer look at the intent-filter tags, their priority is also defined. Here 1 is the lowest priority, therefore when an ordered broadcast is sent in with action specified for these receivers, TruitonReceiverTwo will be called first as it has the highest priority.
package com.truiton.sendorderedbroadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class TruitonReceiverTwo extends BroadcastReceiver { private static String Log_Tag = "TruitonReceiverTwo"; private static String Extras = "Breadcrumb"; @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); results.putString(Extras, Log_Tag); Log.i(Log_Tag, "Priority = 2"); //abortBroadcast(); } }
Here in TruitonReceiverTwo class, result extras from Android sendOrderedBroadcast are captured by getResultExtras() method, and a breadcrumb trail is created. This will be printed in final receiver. Also in this class I have commented out abortBroadcast() method, I’ll explain the significance of it later in tutorial. Next lets have a look at TruitonReceiver class.
package com.truiton.sendorderedbroadcast; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class TruitonReceiver extends BroadcastReceiver { private static String Log_Tag = "TruitonReceiver"; private static String Extras = "Breadcrumb"; @Override public void onReceive(Context context, Intent intent) { Bundle results = getResultExtras(true); String trail = results.getString(Extras); results.putString(Extras, trail + "->" + Log_Tag); Log.i(Log_Tag, "Priority = 1"); } }
Here the code is similar to TruitonReceiverTwo, hence needs no explanation. The only difference is that this BroadcastReceiver has a lower priority i.e. 1, therefore it will be called after the TruitonReceiverTwo. Now if we run Android sendOrderedBroadcast example with priority we should get final receiver result as TruitonReceiverTwo->TruitonReceiver->SendOrderedBroadcastActivity. Have a look at the screen shots:
Here in the third screenshot, I used abortBroadcast() method to abort the broadcast, at the first receiver i.e. TruitonReceiverTwo. This caused the Android sendOrderedBroadcast example with priority to break the normal flow and skip directly to the final result receiver.
With this I can conclude Android sendOrderedBroadcast tutorial. In this tutorial I created a class which fired a sendOrderedBroadcast method of Context class. Which invoked three BroadcastReceivers of which two were prioritized. This resulted in a breadcrumb trail which helped us figure out execution order of BroadcastReceivers. Hope this helped you, if it did please like, +1 and share this tutorial on Google+ and Facebook.
Born in New Delhi, India. A software engineer by profession, an android enthusiast and an evangelist. My motive here is to create a group of skilled developers, who can develop something new and good. Reason being programming is my passion, and also it feels good to make a device do something you want. In a very short span of time professionally I have worked with many tech firms. As of now too, I am employed as a senior engineer in a leading tech company. In total I may have worked on more than 20 projects professionally, and whenever I get spare time I share my thoughts here at Truiton.
Excellent article. Very interesting. Thanks a lot. Keep going.
Awesome tutorial 🙂
Very good article. This made me very close to fully understanding the concepts involved.
I just spent some more time trying to figure out that the first intent you broadcast doesn’t have getResultExtras(true). If you want to send data to the first BroadcasReceiver you just use regular extras.
Thanks a lot.
Hi Mohit,
This example, sendOrderedBroadcast, is a very nice and well and has well defined code. I tried it and it works nice. I have some problem with it; namely I cannot unregister the broadcastreceiver in the onPause() method, since I have no reference to it. I tried to come around that but couldn’t. Would you please help me to do it. Thank you.
Broadcast Receiver is unregistered in the onStop() method . Because it is guaranteed that whenever you navigate back and forth onStop method is called, so to unregister of receiver can only be happen on onStop() method.
Thanks for your simple tutorial. It solved my problem. God bless you.