481

How to use/locate LocalBroadcastManager as described in google docs and Service broadcast doc?

I tried to google it, but there is no code available to start with?

The documents say that I should use it if I want to do broadcast internally with in my app's process but I don't know where to look for this.

Any help/comment?

Update: I know how to use Broadcasts but don't know how to get LocalBroadcastManager available in my project.

4
  • Waqas, have you registered the receiver in manifest. If yes, please let me know how? Commented Apr 3, 2012 at 8:44
  • 2
    I dont think you need to register receiver for such broadcasts in manifest, because if you do, then that receiver will also listen for global broadcasts. Commented Apr 3, 2012 at 8:51
  • 3
    True. Then this means, I have to do it in code as given in the answer below; LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name")); Commented Apr 3, 2012 at 8:54
  • 2
    LocalBroadcastManager has been deprecated. I replaced mine with the EventBus library which is much nicer, imo. Commented Jan 14, 2020 at 4:35

13 Answers 13

890

I'll answer this anyway. Just in case someone needs it.

ReceiverActivity.java

An activity that watches for notifications for the event named "custom-event-name".

@Override public void onCreate(Bundle savedInstanceState) { ... // Register to receive messages. // We are registering an observer (mMessageReceiver) to receive Intents // with actions named "custom-event-name". LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name")); } // Our handler for received Intents. This will be called whenever an Intent // with an action named "custom-event-name" is broadcasted. private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get extra data included in the Intent String message = intent.getStringExtra("message"); Log.d("receiver", "Got message: " + message); } }; @Override protected void onDestroy() { // Unregister since the activity is about to be closed. LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); super.onDestroy(); } 

SenderActivity.java

The second activity that sends/broadcasts notifications.

@Override public void onCreate(Bundle savedInstanceState) { ... // Every time a button is clicked, we want to broadcast a notification. findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendMessage(); } }); } // Send an Intent with an action named "custom-event-name". The Intent sent should // be received by the ReceiverActivity. private void sendMessage() { Log.d("sender", "Broadcasting message"); Intent intent = new Intent("custom-event-name"); // You can also include some extra data. intent.putExtra("message", "This is my message!"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } 

With the code above, every time the button R.id.button_send is clicked, an Intent is broadcasted and is received by mMessageReceiver in ReceiverActivity.

The debug output should look like this:

01-16 10:35:42.413: D/sender(356): Broadcasting message 01-16 10:35:42.421: D/receiver(356): Got message: This is my message! 
Sign up to request clarification or add additional context in comments.

15 Comments

thanks. got it working already. but the problem i faced was to get hold on LocalBroadcastManager class. Since its a support package class, so i wasn't able to use it in my ordinary package till i added Compatibility Library from Android Tools. Once its added, all went just fine. anyway, thanks for the answer
please note that onDestroy() is not guaranteed to be called!!! You must use onPause() (because only onPause() is guaranteed) and onResume() (because it's the match for onPause())
Folks, note what the google docs now say about an Activity after onPause(): Killable = Pre-HONEYCOMB Starting with Honeycomb, an application is not in the killable state until its onStop() has returned.
onDestroy() is no problem. The case in which it is not called is when the app is killed, and it does not matter if you don't unregister in that case since not even the list of registered receivers survives that.
@Selvin I hope you're aware that you can make the BroadcastReciever weakly referenced to the receiving activity and make it unregister itself if it's been orphaned. You don't need to unregister it in onPause, onDestroy is fine as long as you don't use your BroadcastReceiver to keep your activity in RAM. Your example shows a bad practice with an inner class leaking it's outer class, it's not unique to BroadcastReceiver and is something programmers always have to guard against. As for modifying the GUI, you can store a state for when the activity is resumed, you don't have to modify the GUI.
|
135

I'd rather like to answer comprehensively.

  1. LocalbroadcastManager included in android 3.0 and above so you have to use support library v4 for early releases. see instructions here

  2. Create a broadcast receiver:

    private BroadcastReceiver onNotice= new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // intent can contain anydata Log.d("sohail","onReceive called"); tv.setText("Broadcast received !"); } }; 
  3. Register your receiver in onResume of activity like:

    protected void onResume() { super.onResume(); IntentFilter iff= new IntentFilter(MyIntentService.ACTION); LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff); } //MyIntentService.ACTION is just a public static string defined in MyIntentService. 
  4. unRegister receiver in onPause:

    protected void onPause() { super.onPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice); } 
  5. Now whenever a localbroadcast is sent from applications' activity or service, onReceive of onNotice will be called :).

Edit: You can read complete tutorial here LocalBroadcastManager: Intra application message passing

11 Comments

+1. if your Broadcast Receiver is in a fragment, register it using LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice); and unregister it using LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onNotice);
Are you sure that LocalBroadcastManager is included in Android 3.0 and up? Can not find it anywhere except support lib
strangely, LBM is only included in the support library.
I believe you may want to move your lifecycle to onStop because in Android API 24+ with “Multi-Window/Split-View” (enabled by default on API 26+ affaicr), the activity not being interacted with is in the paused state. Source: developer.android.com/guide/topics/ui/…
@AJW I wouldn’t. There’s really no reason to do that (that I can think of). It really depends on your use case. For the most part, onStop/Start tends to be better given that a Dialog will trigger onPause and it may not be desired to “unsubscribe” to things (only to resubscribe moments later) because a Dialog appeared. Or in some cases yes, so… ensure that’s what you want ;)
|
47

On Receiving end:

  • First register LocalBroadcast Receiver
  • Then handle incoming intent data in onReceive.

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.registerReceiver(receiver, new IntentFilter("filter_string")); } public BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent != null) { String str = intent.getStringExtra("key"); // get all your data from intent and do what you want } } }; 

On Sending End:

 Intent intent = new Intent("filter_string"); intent.putExtra("key", "My Data"); // put your all data using put extra LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

1 Comment

In my case only when I set action in intent when sending broadcast works otherwise onReceive() method never called...
27

In Eclipse, eventually I had to add Compatibility/Support Library by right-clicking on my project and selecting:

Android Tools -> Add Support Library

Once it was added, then I was able to use LocalBroadcastManager class in my code.


Android Compatibility Library

Comments

21

localbroadcastmanager is deprecated, use implementations of the observable pattern instead.

androidx.localbroadcastmanager is being deprecated in version 1.1.0

Reason

LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app; any component may listen to events from any other component. It inherits unnecessary use-case limitations of system BroadcastManager; developers have to use Intent even though objects live in only one process and never leave it. For this same reason, it doesn’t follow feature-wise BroadcastManager .

These add up to a confusing developer experience.

Replacement

You can replace usage of LocalBroadcastManager with other implementations of the observable pattern. Depending on your use case, suitable options may be LiveData or reactive streams.

Advantage of LiveData

You can extend a LiveData object using the singleton pattern to wrap system services so that they can be shared in your app. The LiveData object connects to the system service once, and then any observer that needs the resource can just watch the LiveData object.

 public class MyFragment extends Fragment { @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); LiveData<BigDecimal> myPriceListener = ...; myPriceListener.observe(this, price -> { // Update the UI. }); } } 

The observe() method passes the fragment, which is an instance of LifecycleOwner, as the first argument. Doing so denotes that this observer is bound to the Lifecycle object associated with the owner, meaning:

  • If the Lifecycle object is not in an active state, then the observer isn't called even if the value changes.

  • After the Lifecycle object is destroyed, the observer is automatically removed

The fact that LiveData objects are lifecycle-aware means that you can share them between multiple activities, fragments, and services.

4 Comments

you are right about leaking contexts to whole world, but I would like to know what would be a suitable replacement when I want to communicate from a foreground service that is running even without an activity, but when activity comes in, they need to communicate?
Create a singleton class with a LiveData object and post your data from the service. Once the activity launches, activity can easily observe the LiveData without any harm. eg: MyServiceData.getInstance().getMyData().observe ...
I will miss LocalBroadcastManager. If it was confusing to developers at Google, perhaps they need to stop over-engineering things?
@Darish Would this singleton class be equivalent to storing it in the Application object? Why is this kind of global state in these cases not considered bad practice?
15

How to change your global broadcast to LocalBroadcast

1) Create Instance

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this); 

2) For registering BroadcastReceiver

Replace

registerReceiver(new YourReceiver(),new IntentFilter("YourAction")); 

With

localBroadcastManager.registerReceiver(new YourReceiver(),new IntentFilter("YourAction")); 

3) For sending broadcast message

Replace

sendBroadcast(intent); 

With

localBroadcastManager.sendBroadcast(intent); 

4) For unregistering broadcast message

Replace

unregisterReceiver(mybroadcast); 

With

localBroadcastManager.unregisterReceiver(mybroadcast); 

2 Comments

How can I register multiple IntentFilter??
@ParikshitChalke: link
6

When you'll play enough with LocalBroadcastReceiver I'll suggest you to give Green Robot's EventBus a try - you will definitely realize the difference and usefulness of it compared to LBR. Less code, customizable about receiver's thread (UI/Bg), checking receivers availability, sticky events, events could be used as data delivery etc.

Comments

5

Kotlin version of using LocalBroadcastManager:

Please check the below code for registering, sending and receiving the broadcast message.

class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // register broadcast manager val localBroadcastManager = LocalBroadcastManager.getInstance(this) localBroadcastManager.registerReceiver(receiver, IntentFilter("your_action")) } // broadcast receiver var receiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent != null) { val str = intent.getStringExtra("key") } } } /** * Send broadcast method */ fun sendBroadcast() { val intent = Intent("your_action") intent.putExtra("key", "Your data") LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } override fun onDestroy() { // Unregister broadcast LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver) super.onDestroy() } } 

Comments

2

An example of an Activity and a Service implementing a LocalBroadcastManager can be found in the developer docs. I personally found it very useful.

EDIT: The link has since then been removed from the site, but the data is the following: https://github.com/carrot-garden/android_maven-android-plugin-samples/blob/master/support4demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.java

Comments

0
enter code here if (createSuccses){ val userDataChange=Intent(BRODCAST_USER_DATA_CHANGE) LocalBroadcastManager.getInstance(this).sendBroadcast( userDataChange ) enableSpinner(false) finish() 

Comments

0

By declaring one in your AndroidManifest.xml file with the tag (also called static)

<receiver android:name=".YourBrodcastReceiverClass" android:exported="true"> <intent-filter> <!-- The actions you wish to listen to, below is an example --> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> 

You will notice that the broadcast receiver declared above has a property of exported=”true”. This attribute tells the receiver that it can receive broadcasts from outside the scope of the application.
2. Or dynamically by registering an instance with registerReceiver (what is known as context registered)

public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter); public void onReceive(Context context, Intent intent) { //Implement your logic here } 

There are three ways to send broadcasts:
The sendOrderedBroadcast method, makes sure to send broadcasts to only one receiver at a time. Each broadcast can in turn, pass along data to the one following it, or to stop the propagation of the broadcast to the receivers that follow.
The sendBroadcast is similar to the method mentioned above, with one difference. All broadcast receivers receive the message and do not depend on one another.
The LocalBroadcastManager.sendBroadcast method only sends broadcasts to receivers defined inside your application and does not exceed the scope of your application.

Comments

0

I am an iOS dev, so I made a solution similar to NotificationCenter:

object NotificationCenter { var observers: MutableMap<String, MutableList<NotificationObserver>> = mutableMapOf() fun addObserver(observer: NotificationObserver, notificationName: NotificationName) { var os = observers[notificationName.value] if (os == null) { os = mutableListOf<NotificationObserver>() observers[notificationName.value] = os } os.add(observer) } fun removeObserver(observer: NotificationObserver, notificationName: NotificationName) { val os = observers[notificationName.value] if (os != null) { os.remove(observer) } } fun removeObserver(observer:NotificationObserver) { observers.forEach { name, mutableList -> if (mutableList.contains(observer)) { mutableList.remove(observer) } } } fun postNotification(notificationName: NotificationName, obj: Any?) { val os = observers[notificationName.value] if (os != null) { os.forEach {observer -> observer.onNotification(notificationName,obj) } } } } interface NotificationObserver { fun onNotification(name: NotificationName,obj:Any?) } enum class NotificationName(val value: String) { onPlayerStatReceived("on player stat received"), ... } 

Some class that want to observe notification must conform to observer protocol:

class MainActivity : AppCompatActivity(), NotificationObserver { override fun onCreate(savedInstanceState: Bundle?) { ... NotificationCenter.addObserver(this,NotificationName.onPlayerStatReceived) } override fun onDestroy() { ... super.onDestroy() NotificationCenter.removeObserver(this) } ... override fun onNotification(name: NotificationName, obj: Any?) { when (name) { NotificationName.onPlayerStatReceived -> { Log.d(tag, "onPlayerStatReceived") } else -> Log.e(tag, "Notification not handled") } } 

Finally, post some notification to observers:

NotificationCenter.postNotification(NotificationName.onPlayerStatReceived,null) 

Comments

-4

we can also use interface for same as broadcastManger here i am sharing the testd code for broadcastManager but by interface.

first make an interface like:

public interface MyInterface { void GetName(String name); } 

2-this is the first class that need implementation

public class First implements MyInterface{ MyInterface interfc; public static void main(String[] args) { First f=new First(); Second s=new Second(); f.initIterface(s); f.GetName("Paddy"); } private void initIterface(MyInterface interfc){ this.interfc=interfc; } public void GetName(String name) { System.out.println("first "+name); interfc.GetName(name); } } 

3-here is the the second class that implement the same interface whose method call automatically

public class Second implements MyInterface{ public void GetName(String name) { System.out.println("Second"+name); } } 

so by this approach we can use the interface functioning same as broadcastManager.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.