I have an activity, it needs to response to a broadcast event.
Since an activity can not be a broadcast receiver at the same time,
I made a broadcast receiver.
My question is: how can I notify the activity from the broadcast receiver?
I believe this is a common situation, so is there a design pattern for this?
The broadcast is the notification. :) If you want to say, start an activity or a service, etc., based on a received broadcast then you need a standalone broadcast receiver and you put that in your manifest file. However, if you want your activity itself to respond to broadcasts then you create an instance of a broadcast receiver in your activity and register it there.
The pattern I use is:
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(BROADCAST_ACTION);
this.registerReceiver(this.receiver, filter);
}
public void onPause() {
super.onPause();
this.unregisterReceiver(this.receiver);
}
}
So, 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.
Related
I am trying code for LocalBroadcastManager.While register and unregister BroadcastReceiver , I am using below code.
Can any one give difference between both way to register and unregister
LocalBroadcastManager?
First Way:
...
//Register receiver
registerReceiver(mPairingReceiver, IntentFilter filter = new IntentFilter("android.bluetooth.device.action.PAIRING_REQUEST"));
...
#Override
protected void onStop() {
super.onStop();
// unregister receiver
unregisterReceiver(mPairingReceiver);
}
Second Way:
...
//Register receiver
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(mPairingReceiver, IntentFilter filter = new IntentFilter("android.bluetooth.device.action.PAIRING_REQUEST"));
...
#Override
protected void onStop() {
super.onStop();
// unregister receiver
LocalBroadcastManager.getInstance(MainActivity.this).unregisterReceiver(mPairingReceiver);
}
Your first snippet calls unregisterReceiver() on a Context. This unregisters a receiver that you registered via registerReceiver() on the same Context. These methods are for system-level broadcasts.
Your second snippet calls unregisterReceiver() on a LocalBroadcastManager. This unregisters a receiver that you registered via registerReceiver() on the same LocalBroadcastManager. These methods are for local broadcasts, solely within your own application.
I want to ask a question.
I have make a button that starts and stops a background service.
I make a class SmsReceiver which reads an incoming sms.
So i want when the service is start to call the the Sms BroadcastReceiver.
Any ideas or any other idea how to read an sms with background service?
If you already have the SmsReceiver working fine,all you need to do is register it from the Service.To do that you need to override the Service's onCreate().
Your Service should look something like this:
public class SmsService extends Service
{
private SmsReceiver receiver; //global so we can unregister it when the time comes.
public void onCreate ()
{
super.onCreate ();//call to super
//make a new intent filter so that all incoming SMS get to you as well
IntentFilter smsFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
receiver = new SmsReceiver(); //make a new SmsReceiver
registerReceiver(receiver, smsFilter); //register the Receiver
}
public void onDestroy ()
{
unregisterReceiver (receiver); //unregisters the Receiver if Service is killed
super.onDestroy();
}
}
In the manifest, be sure to include the necessary SMS permissions and remember to also declare the Service in the manifest.
<service android:name=".SmsService" >
</service>
I want to use BroadcastReceiver in my application as AsyncTask result indicator in different Activities and therefore AsyncTasks too. I think my approach is little wrong or I missed something.
Here what I'm doing: Firstly, during onCreate I registered my receiver as a BroadcastReceiver using the registerReceiver method. My receiver looks like:
protected BroadcastReceiver myReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String msg_for_me = intent.getStringExtra("some_msg");
Log.i("Tutorial", msg_for_me);
}
}
In my application, I've A and B activities. Each have different receivers which getting messages from different tasks. By the way, I must clarify that, A activity starting B activity.
I'm using receiver which in activity A, then activity A starting B using the startActivity. In activity B, I'm executing an AsyncTask and on onPostExecute I'm sending a broadcast with B activity's context. But somehow still A activity's receiver getting message. Both receivers have the same content but have different names.
So here are my issues:
Should I unregisterReceiver when I started new activity on onPause method?
Is BroadcastReceiver that how I'm using, only for one call? Should I register again and again whenever I send any message?
I'm pretty sure I didn't define any receiver to Manifest. I suppose this is what I'm doing wrong. If this is well, how can I use IntentFilter while sending broadcast?
Please let me know if there is uncertain question. Any clues about BroadcastReceiver would be great and appriciated.
Yes, you should unregister broadcast receiver on activity pause. It
is the potential leak.
No broadcast receivers are not for one call.
They are called everytime the broadcast is done for the registered
intents.
You can register the receiver for particular intent on
OnResume like this,
mContext.registerReceiver(iReceiver, new android.content.IntentFilter("android.intent.action.BATTERY_CHANGED"));
Where iReceiver is ,
iReceiver = new IntentReceiver();
private class IntentReceiver extends BroadcastReceiver {
private final String LOG_TAG="IntentReceiver";
#Override
public void onReceive(Context arg0, Intent intent) {
}
}
and unregister the same on OnPause
mContext.unregisterReceiver(iReceiver);
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
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.