13

I have an Activity in which I am registering a BroadcastReceiver locally as follows:

public class SomeActivity extends Activity{

    public static final String PERFORM_SOME_ACTION = "PERFORM_SOME_ACTION";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.some_activity_layout);

        .....
        .....

        IntentFilter filter = new IntentFilter();
        filter.addAction(PERFORM_SOME_ACTION);

        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // perform some action ...
            }
        };

        registerReceiver(receiver, filter);
    }

    .....
    .....
}

And I have a Service from which I broadcast an Intent as follows:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {        

    Intent i = new Intent(SomeActivity.PERFORM_SOME_ACTION);
    sendBroadcast(i);   /* Send global broadcast. */

    return START_STICKY;
}

This works as intended. After having implemented this, I realized that a local broadcast would be more appropriate for this situation:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {        

    Intent i = new Intent(SomeActivity.PERFORM_SOME_ACTION);
    LocalBroadcastManager.getInstance(this).sendBroadcast(i);   /* Send local broadcast. */

    return START_STICKY;
}

Unfortunately, the above scheme doesn't work. A global broadcast is sent every time, while a local broadcast is apparently never sent/received.

What am I missing here? Can't local broadcasts be sent between two distinct app components, like two separate Activitys or from a Service to an Activity? What am I doing wrong??

Note:

As per the documentation, it is more efficient and more to the point to send a local broadcast (an intra-app broadcast whose scope is restricted to the app's own components) rather than a global broadcast (an inter-app broadcast which is transmitted to every single app on the phone) whenever we do not need the broadcast to propagate outside the application. This is the reason for making the aforementioned change.

Yash Sampat
  • 30,051
  • 12
  • 94
  • 120
  • 4
    You also need `LocalBroadcastManager.getInstance(this).registerReceiver();` along with `LocalBroadcastManager.getInstance(this).sendBroadcast(i);` – Shaishav Aug 26 '16 at 05:05
  • 1
    @Shaishav: That worked. You can post it as an answer; I will mark it as the correct one (you were the first). However, is there some concept that I am missing here? So a local broadcast would only be received by a `BroadcastReceiver` registered locally? – Yash Sampat Aug 26 '16 at 05:30
  • Yeah...a broadcast sent using a `LocalBroadcastManager` instance can only be received by a receiver registered using a `LocalBroadcastManager` instance. Not exactly sure how to answer the *why* part. Other than this I don't really have much to add to 'ρяσѕρєя K's' answer. – Shaishav Aug 26 '16 at 05:39
  • 1
    I had the same problem as the OP - because I was calling `setData(myUri)` on my broadcastIntent. Also, it maybe worth checking the context objects you are using to register the receivers / sending the broadcast intents with. – ban-geoengineering Jan 17 '17 at 23:26
  • @ban-geoengineering: Can you elaborate on that last sentence? Do you mean that if you use an activity context to register the receiver but use an app context to send the broadcast, the receiver may not receive the broadcast? – LarsH Jul 12 '17 at 17:58
  • 1
    @LarsH Yes, that's what I meant. I'm not sure if it could be the case or not, but it is one of the things I was considering as a possibility before I discovered that `setData(myUri)` was actually my problem - so I didn't explore the idea any further. But you should be able to check easily enough by using `getApplicationContext()` (or whatever) on both sides. (I just thought I'd throw it out there in case there was a chance it might help someone else.) – ban-geoengineering Jul 12 '17 at 20:00
  • @ban-geoengineering: Thanks. When I encountered a similar problem (https://stackoverflow.com/questions/45064518/why-isnt-my-local-broadcast-from-a-service-being-received), I tried using `getApplicationContext()` because of your previous comment. In my case, it didn't help. – LarsH Jul 12 '17 at 20:06

1 Answers1

22

What am I missing here?

Use LocalBroadcastManager for registering LocalBroadcast, currently using registerReceiver method of Activity which is used for registering global Broadcast:

LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
  • 2
    Thank you, but please explain why a local broadcast would only be received by a `BroadcastReceiver` registered locally. – Yash Sampat Aug 26 '16 at 05:35
  • @Y.S.: What do mean by `BroadcastReceiver registered locally` ? in posted code you have just problem because you are using `LocalBroadcastManager` to send broadcast but `PERFORM_SOME_ACTION` Action is registered for global broadcast using `registerReceiver` method of Activity. – ρяσѕρєя K Aug 26 '16 at 05:45