I had to implement a feature to this app which consists of an Activity
and a Service
working on the background (it implements Service
, not IntentService
).
I went through a few tutorials on the Internet that are supposed to work, and they all use LocalBroadcastManager
, which by the way is the recommended by Android:
If you don't need to send broadcasts across applications, consider using this class with
LocalBroadcastManager
instead of the more general facilities described below.
I literally lost a day to find out the problem why it wouldn't work for me: it only works if I use Context.sendBroadcast()
. and Context.registerReceiver()
instead of the LocalBroadcastManager
methods.
Now my app is working, but I feel I am going against the best practices, and I don't know why. Any ideas why it could be happening?
EDIT:
After I wrote this question I went further on the problem. LocalBroadcastManager
works through a Singleton, as we should call LocalBroadcastManager.getInstance(this).method()
. I logged both instances (in the Activity
and in the Service
) and they have different memory addresses.
Now I came to another question, shouldn't a Service
have the same Context
as the Activity
that called it? From this article a Service runs on the Main Thread, hence I'd think the Context
would be
the same.
Any thoughts on that? (sorry for the long post)
Code samples:
MyService
public class MyService extends Service {
...
// When an event is triggered, sends a broadcast
Intent myIntent = new Intent(MainActivity.MY_INTENT);
myIntent.putExtra("myMsg","msg");
sendBroadcast(myIntent);
// Previously I was trying:
// LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(myIntent);
}
MyActivity
public class MainActivity {
...
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive", "received!");
// TODO something
}
};
@Override
protected void onResume() {
super.onResume();
registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
// Previously I was trying:
// LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(messageReceiver, new IntentFilter(MY_INTENT));
}
}
Declaration:
private BroadcastReceiver receiver;
Initialization:
receiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
//todo
}
};
Registration:
LocalBroadcastManager.getInstance(context).registerReceiver(receiver, new IntentFilter("RECEIVER_FILTER"));
context
can be any type of Context
, you can use the application context.
Unregister:
LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
Broadcast:
Intent intent = new Intent("RECEIVER_FILTER");
intent.putExtra("EXTRA", someExtra);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);