BroadcastReceiver receives more Intents than sent - android

I have next problem:
I create a custom BroadcastReceiver and register it in main activity onCreate handler:
public class MainActivity extends ListActivity {
private static final LogReceiver logReceiver = new LogReceiver();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(logReceiver, new IntentFilter(LogReceiver.ACTION_LOG));
}
...
}
BroadcastReceiver class:
public class LogReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("intent", "intent <-");
}
}
Then I send multiple Intents from a local service using next code:
Intent intent = new Intent(LogReceiver.ACTION_LOG).putExtra("log", logString);
localBroadcastManager.sendBroadcast(intent);
Log.i("intent", "intent ->");
The log looks very strange for me:
intent ->
intent <-
intent ->
intent <-
intent <-
intent ->
intent <-
intent <-
intent <-
...
The 1st time LogReceiver receives only one Intent and this is correct but each next time it receives more equal Intents than sent.
I can switch from Intent approach in my project but just interesting why this happens?

You should deregister the receiver in the onDestroy of the Activity.
Additionally you should check if this receiver really has to be static.
If you need the receiver throughout the application it should be saved in a separate singleton class or in a custom Application class instead of one Activity.
You could then register the receiver in the first started Activity. But you should make sure it is registered only once for example by storing a boolean registered into the receiver that is checked before registering at the LocalBroadcastManager.

Related

My Activity not receiving Local Broadcasts sent from another activity

I'm just getting familiarised with the Local Broadcast Messages. I have 2 activities.
MainActivity :
I have 2 buttons. On the click of 1 button, I'm broadcasting the message. On the click of another one, I'm navigating to second Activity.
public class MainActivity extends AppCompatActivity {
Button btn;
Button btn1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button)findViewById(R.id.sendBroadCast);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
btn1 = (Button)findViewById(R.id.btn);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
}
void sendMessage(){
Log.d("RAK","Gonna send braodcast");
Intent intent = new Intent("customMsg");
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
Second Activity :
Registering for the receiver in onCreate of this activity.
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("RAK","In oncreate of second activity.Registered for local receiver");
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("customMsg"));
}
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() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
}
The issue I'm facing is, the second Activity is not receiving the broadcast. Please help me.
P.S : Please dont mark this a duplicate. I have followed this link : how to use LocalBroadcastManager?
Thanks,
Rakesh
So as to receive the broadcast the second activity should be up and running while the first one is sending a broadcast, which is going to be hard in your case (2 activities not running at same time).
Your first Activity sends the broadcast, but no activity (in your case second activity) is launched yet so the messgae get 'lost'.
You could test by broadcasting from within a service for example, and your second activity running. Then, the activity could handle/receive it.
What you may want to do is passing a String to the secondActivity using extraData. If you wish to test BroadcastReceiver, then, try with a service sending the broadcast !
The problem is your registering your broadcast receiver inside onCreate() of second activity, that means the second activity should have been previous launched before you broadcast your intent keeping in mind that your do not unregister it when the second activity is destroyed.
Alternative you can register your receiver statically in the Manifest file
public class Receiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
// Whatever
}
}
Manifest
<receiver
android:name=".Receiver"
android:exported="false" >
<intent-filter>
<action android:name="customMsg" />
</intent-filter>
</receiver>
NOTE:
Registering statically ensure that the the receiver is registered at system boot time or when the application is added at run time

Android Change a variable in service from other app

the title says all, I need to change the variable of my service from a activity in my other app , what to finalize the service or not, this is possible?
I found the Message object , but I do not quite understand
The simplest solution would be to implement a BroadcastReceiver. Your Service listens for the Broadcast and the other App sends the Broadcast.
Example Reciever:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Get bundle from intent and use it to set your Variable in your Service
}
}
Example Broadcaster (courtesy of Vogella):
Intent intent = new Intent();
intent.setAction("de.vogella.android.mybroadcast");
sendBroadcast(intent);

send action from receiver to activity?

I am using broadcast receiver in my app to detect incomming call and it works fine. But problem is I can not send action to activity. I mean.. I want do something in activity not in receiver. I read many tutorial but they all are performing action in receiver. Any idea ?
You can declare a BroadcastReceiver as inner class of the Activity. In this case you can directly call activity's methods:
public class MyActivity extends Activity {
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
activityMethod();
}
};
private final IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");
#Override
protected void onStart() {
super.onResume();
registerReceiver(receiver, filter);
}
#Override
protected void onStop() {
super.onPause();
unregisterReceiver(receiver);
}
private void activityMethod() {
}
}
You can start the Activity using an Intent and put a command code in the Intent extra fields. In your Activity you can then decide the behaviour based on the command code or resort to a default behaviour if none is present.
You can start an activity from your receiver via the normal means:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, YourActivity.class);
startActivity(i);
}
Note though that the user is going to expect that the phone application starts up since they are receiving a phone call. It is very likely a bad idea to hijack the phone call by dumping your own activity on top of the stock dialer app.

Passing a string from an activity to a broadcast receiver

I am having a problem while passing a string from my main activity to my broadcast receiver when the app is not currently open on the screen.
When the MainActivity class is created the intent filter returns the correct information through the broadcast receiver but as soon as the user goes to the homescreen on their phone the broadcast receiver starts returning "null" for the toast when the receiver is triggered offscreen.
1. New Intent
Intent home_page = new Intent(newIntent.this,MainActivity.class);
ownAddress = ""+customInput.getText().toString();
home_page.putExtra("session_number", ""+ownAddress);
startActivity(home_page);
2. MainActivity.java:
public class MainActivity extends DroidGap {
SmsReceiver mAppReceiver = new SmsReceiver();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
final String ownAddress = bundle.getString("session_number");
registerReceiver(mAppReceiver, new IntentFilter("SmsReceiver"));
Intent intent = new Intent("SmsReceiver");
intent.putExtra("passAddress", ownAddress);
sendBroadcast(intent);
}
}
3. SmsReceiver.java:
public class SmsReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast showme = Toast.makeText(context,"Number: "+intent.getExtras().get("passAddress"),Toast.LENGTH_LONG);
showme.show();
}
}
Is there anyway to pass the string through to the broadcast receiver while the app is only running in the background or regardless of when the MainActivity class is created?
I may be wrong here but, logically, the reason why "the broadcast receiver starts returning "null" for the toast when the receiver is triggered offscreen" is because the context that you pass to the onReceive constructor is destroyed when the user goes to the homescreen.
I guess one solution for passing the string would be to create a public static string variable in MainActivity which is used to store the string value you want to pass. Then all you have to do is access this string statically in your BroadcastReceiver.

Intent not received by activity

I have a main activity that launches a service to do a web search in the background and I would like the main activity to get an intent when the search is done.
In my main activity , I defined a BroadcastReceiver and an Intent Filter to listen to the "end of search" intent:
public class AgeRage extends Activity {
// Listener to all results from background processes
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ImageSearchService.SEARCH_RESULT_ACTION)) {
0);
Toast.makeText(context,"Got " + i + "results", Toast.LENGTH_SHORT).show();
}
else Toast.makeText(context,"unknown intent", Toast.LENGTH_SHORT).show();
}
};
IntentFilter receiverFilter = new IntentFilter ();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Register to image search service messages
receiverFilter.addAction(ImageSearchService.SEARCH_RESULT_ACTION);
registerReceiver(receiver,receiverFilter);
...
In the service , I do the search and when it is done , I send an Intent:
public class ImageSearchService extends IntentService {
...
protected void onHandleIntent (Intent intent) {
... doing search ...
Intent i = new Intent (this,AgeRage.class);
i.setAction (SEARCH_RESULT_ACTION);
i.putExtra(SEARCH_STATUS, (searchStatus ==SearchStatus.DONE) ? true:false);
i.putExtra (SEARCH_RESULT_NUM, totalResultNum);
i.putExtra (SEARCH_ID, searchID);
sendBroadcast (i,null);
}
But, the main activity doesn't get the Intent. I know that the sendBroadcast is being called and the the receiver's OnReceive is not (checked with a debugger).
I assume that since I create the filter dynamically , I do not need to define a filter in the manifest file.
Am I doing something wrong ?
Thanks
Isaac
Ok. Well I just checked mine and we are doing it the same way, however ...
ImageSearchService.SEARCH_RESULT_ACTION
Try doing com.yourpackagename.ImageSearchSrvice.SEARCH_RESULT_ACTION
where SEARCH_RESULT_ACTION is a public static string variable. See if that helps.
I think it must be the naming of the ACTION. Also note that you might want to run tru the breakpoints and just check log. do intent.getAction() and print this out rather than checking inside the if statement. Just always print it out and see. Don't need to break inside a broacast receiver it will crash after a while.

Categories

Resources