Working with BroadcastReceiver - android

I have defined a BroadcastReceiver in my activity in the following way to get results from an IntentService running on another thread:
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isSyncCompleted = intent.getBooleanExtra("issynccompleted", false);
if (isSyncCompleted){
showAlert("Sync completed in service");
}
context.unregisterReceiver(receiver);
}
};
//register receiver for service
registerReceiver(receiver, new IntentFilter(ContentSyncService.SERVICE_INTENT_FILTER));
Note that I am unregistering my receiver in the onReceive code block and not in onPause. That is because I want to have the receiver listening even when the activity has been destroyed.
But I keep getting the error: "Activity ... has leaked IntentReceiver ... that was originally registered here. Are you missing a call to unregisterReceiver()?"

This solution works for me, I override the Activity methods, not a BrodcastReceiver:
#Override
protected void onPause() {
super.onPause();
// unregister receiver
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mMessageReceiver);
}
#Override
protected void onResume() {
super.onResume();
// register receiver
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("your.package.name"));
}

Only will unregister receiver if you receive action at least one time.
So you need unregister your receiver in OnPause (and in other place if you need), because there you are safe that always will unregister the receiver.

Intead of use context.unregisterReceiver(receiver) inside your receiver,
Try it:
activity.unregisterReceiver(this);

Related

BroadcastReceiver lifecycle

1) I have an Activity. This Activity starts a service, which in turn creates and registers a BroadcastReceiver.
2) I have an Activity. This Activity creates and registers a BroadcastReceiver.
When does BroadcastReceiver's life end in each of the above cases? In other words - when it gets destroyed and won't listen to broadcasts anymore?
Declare broadcast receiver in manifest to achieve independent life cycle for it.
http://developer.android.com/reference/android/content/BroadcastReceiver.html
Only onReceive() method is called in BroadcastReciver's life cycle.
A BroadcastReciever life cycle ends (ie stop receiving broadcast) when you unregister it. usually you would do this in the onPause/onStop method. but it's up to you technically.
Example:
#Override
public void onResume() {
super.onResume();
// Register mMessageReceiver to receive messages.
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("my-event"));
}
// handler for received Intents for the "my-event" event
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
#Override
protected void onPause() {
// Unregister since the activity is not visible
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}

How to handel if n/w is gone in betwwn

I am working on an application which uses internet on every Activity. I am checking the connection onCreate of every Activity. But if n/w(Internet) is gone in between how can i know. is there any Method which can notify whenever the Network has gone during Application.
in each Activity class you can add this broadcast receiver in the onReceive method you can interact with the activity this is an example
public class MyActivity extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(...) {
...
}
});
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
this.registerReceiver(this.receiver, filter);
}
public void onPause() {
super.onPause();
this.unregisterReceiver(this.receiver);
}
}
this way the receiver is instantiated when the class is created (could also do in onCreate). Then in the onResume/onPause I handle registering and unregistering the receiver. Then in the reciever's onReceive method I do whatever is necessary to make the activity react the way I want to when it receives the broadcast.
There is a CONNECTIVITY_CHANGE broadcast which you can listen to get the updates about the connection. Here are some more details http://groups.google.com/group/android-developers/browse_thread/thread/ce1c3ed3e39a0c81

Update the UI of the calling activity or start a new activity when the alarm is triggered from a broadcast receiver

I am writing an alarm code and using a broadcast receiver. I am able to receive the broadcast receiver. but now I want to come back to the calling activity and update the UI of my activity. I am not able to this.
I used the following code in my activity but it is never executing that code.
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I am back!!", Toast.LENGTH_LONG).show();
}
};
#Override
protected void onPause()
{
super.onPause();
unregisterReceiver(myBroadcastReceiver);
}
#Override
protected void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter("com.test.Main");
registerReceiver(myBroadcastReceiver, intentFilter);
}
in the manifest file I have included the following, here gotAlarm is the broadcast receiver file
<receiver android:name=".gotAlarm"
android:enabled="true">
</receiver>
gotAlarm file is one which gets called from the pending intent of the alarm set
public class gotAlarm extends BroadcastReceiver {
public void onReceive(Context context, Intent intent){
Toast.makeText(context, "Wake Up!!", Toast.LENGTH_LONG).show();
}
}
May be I am missing something very basic.
please help.
Two things:
If you dynamically register the receiver via Context.registerReceiver() then you won't receive broadcasts when Activity is paused (or stopped or not-running). If you need to receive broadcasts even when Activity is paused then create a top-level BroadcastReceiver class (as opposed to your inner class) and use <receiver> to register it.
BroadcastReceiver lifecycle docs state that BroadcastReceiver object is alive only during processing of onReceive(). You can not do any async tasks like showing dialogs, etc.. In your case (Activities might not be running and you receive a broadcast) you should use NotificationManager to notify user something happened.
I have dropped this way and I am starting a new activity on receiving broadcast. And I am sending information data from calling activity to broadcast and from broadcast to next activity. This has served the purpose.
Did you register your BroadcastReceiver (you can do this in the 'onResume'-method of your Activity)? Also, you should unregister your BroadcastReceiver in the 'onPause'-method.

Weird "Receiver not registered" exception

In onResume() I do:
registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
and in onPause():
unregisterReceiver(timeTickReceiver);
I see "java.lang.IllegalArgumentException: Receiver not registered" reports in Android Developer Console (there are only 2 reports and my app has thousands of users). The exception is triggered by unregisterReceiver(). What can be happening? I don't feel very confident to just surround it with try-catch.
We've seen this error when doing a long press on a particular screen, and then immediately doing two orientation changes (e.g. turning the device upside down).
The API docs for unregisterReceiver says:
Unregister a previously registered BroadcastReceiver.
It doesn't say explicitly, but as you've seen, you hit IllegalArgumentException: Receiver not registered if it isn't already registered.
The workaround I'm using is to store my Receiver as a member field, and have it set to null whenever it is not registered, i.e. I initialize it to null, and then only set it when I register it. This might not be perfect, but it does solve my crashes!
private Receiver mReceiver = null;
From my onServiceConnected:
sLog.debug("Registering receiver");
mReceiver = new Receiver();
registerReceiver(mReceiver, filter);
From my onServiceDisconnected:
if (mReceiver == null)
{
sLog.info("Do not unregister receiver as it was never registered");
}
else
{
sLog.debug("Unregister receiver");
unregisterReceiver(mReceiver);
mReceiver = null;
}
A broadcast receiver should be unregister in the onPause() lifecycle method
protected void onPause() {
this.unregisterReceiver(reciever);
super.onPause();
}
Easiest option would be to wrap try/catch block around the code.
try{
...
this.unregisterReceiver(reciever);
}
catch(IllegalArgumentException e)
{
// TODO: handle exception
}
catch (Exception e) {
// TODO: handle exception
}
I guess there may be some states where the receiver is not actually registered before e.g. a user exits the app.
You might want to try adding a check for the receiver before running unregister, (I've done this in several cases):
protected void onPause() {
if(timeTickReceiver != null) {
unregisterReceiver(timeTickReceiver);
}
}
A BroadcastReceiver should be registered in the onCreate() lifecycle method:
private BroadcastReceiver receiver;
#Overrride
public void onCreate(Bundle savedInstanceState){
IntentFilter filter = new IntentFilter();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
...
}
}
registerReceiver(receiver, filter);
}
And a BroadcastReceiver should be unregistered in the onDestory() lifecycle method:
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
}
This will prevent the scenario of unregistering a BroadcastReceiver that has not yet been registered.

Where to register a BroadcastReceiver (Activity lifecycle fun)

Where's the right place to register/unregister an intent receiver in an Activity? Usually I would put stuff like this here:
class MyActivity
{
private BroadcastReceiver mMyReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "Do something.");
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(mMyReceiver, new IntentFilter(...));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(mMyReceiver);
}
}
The problem is that my activity can then no longer respond to the broadcast if it happens while it's in the pause state. Where's the right place to do something like this then?
Thanks
I think the following link might be useful to you
http://android-journey.blogspot.com/2010/01/android-braodcast-receivers.html
This should work in your case:
Unregister in onDestroy().
I think in your case, you can register the receiver in the onCreate() and unregister in the onDestroy(). This will keep it registered, even after it's been paused, until the activity is destroyed.
I had the reverse problem. I had originally registered my receivers in the onCreate() and when my activity was paused, I still got logs that it was receiving broadcasts. I moved it to the onResume, as you have, and that problem went away.

Categories

Resources