My Activity not receiving Local Broadcasts sent from another activity - android

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

Related

Check for internet on all activity and show message WHILE net is disconnected

AIM
Here is what I want to do:
Check for internet connection at all the times in all the activities of my application (I have like 13 activities so far).
If net is working then all is fine.
If net is not working, show a message (using RelativeLayout) which will be displayed WHILE user is offline i.e. until net works again, that message will be there (on whatever activity user goes to)
Previous Attempts
Here is what I tried:
I tried to create a class that extends Broadcast Receiver. I created an object of that class on all the activities and registered the receiver.
In my class, whenever net status changes, the main class sends a message through Intent to activity and then activity receives and checks the message (Code is below).
Here is the problem:
I never unregistered receiver which of course gave me an error.
Are you missing a call to unregisterReceiver()?
If I unregistered the receiver, it gave me following error:
java.lang.IllegalArgumentException: Receiver not registered
Code in Activites
// The onCreate function (Just a sample)
onCreate(){
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
// Outside OnCreate
NetworkStatus broadcastReceiver = new NetworkStatus() {
#Override
public void onReceive(Context context, Intent intent) {
String message;
Bundle b = intent.getExtras();
message = b.getString(KEY_NET_MESSAGE);
if (message.equals(KEY_NET_DISCONNECTED)){
Toast.makeText(SignupActivity.this, MESSAGE_NET_DISCONNECTED, Toast.LENGTH_SHORT).show();
btnSignup.setEnabled(false);
Network_disconnection.setVisibility(View.VISIBLE);
}
if (message.equals(KEY_NET_CONNECTED)){
btnSignup.setEnabled(true);
Network_disconnection.setVisibility(View.INVISIBLE);
}
}
};
//onStop, just a sample
#Override
protected void onStop() {
unregisterReceiver(broadcastReceiver);
super.onStop();
}
AndroidManifest.xml
<receiver android:name=".Common.NetworkStatus">
-
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
NetworkStatus.java
public class NetworkStatus extends BroadcastReceiver implements Keys.UniversalKeys{
#Override
public void onReceive(Context context, Intent arg1) {
boolean isConnected = arg1.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if(isConnected){
Intent i = new Intent("broadCastName");
// Data you need to pass to activity
i.putExtra(KEY_NET_MESSAGE, KEY_NET_DISCONNECTED);
context.sendBroadcast(i);
}
else{
Intent i = new Intent("broadCastName");
// Data you need to pass to activity
i.putExtra(KEY_NET_MESSAGE, KEY_NET_CONNECTED);
context.sendBroadcast(i);
Toast.makeText(context, KEY_NET_CONNECTED, Toast.LENGTH_LONG).show();
}
}
}
Question
What am I doing wrong? One thing is clear to me that maybe I should not create new receiver on each activity! Also, why do I need to make an extra java file? I mean why I just can't create a BroadcastReceiver object on each activity and go on with it?
Understanding XML vs JAVA
When you register a receiver in AndroidMainfest.XML, it's static. It will run even if application is closed.
When you register a receiver in JAVA (Activity) it's dynamic and it can be registered and unregistered via coding dynamically.
Solution
Create a class SampleActivity.java with following code:
public class SampleActivity extends AppCompatActivity {
// Declare BroadcastReceiver and RelativeLayout
BroadcastReceiver breceiver;
RelativeLayout NoNetBar;
#Override
protected void onResume() {
Toast.makeText(SampleActivity.this, "App has Resumed", Toast.LENGTH_SHORT).show();
// Register your receiver upon resume.
registerReceiver(breceiver, new IntentFilter("broadCastName"));
Toast.makeText(SampleActivity.this, "Broadcast Registered", Toast.LENGTH_SHORT).show();
super.onResume();
}
public void setRelative(RelativeLayout param_bar) {
Toast.makeText(SampleActivity.this, "NoNetBar has been setup", Toast.LENGTH_SHORT).show();
// This will set RelativeLayout to your desired RelativeLayout from your main activity
NoNetBar = param_bar;
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
// Call super oncreate and then set RelativeLayout to invisible initially
super.onCreate(savedInstanceState);
NoNetBar.setVisibility(View.INVISIBLE);
// Initialize broadcast receiver
breceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean isConnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (isConnected){
NoNetBar.setVisibility(View.VISIBLE);
} else if (!isConnected){
NoNetBar.setVisibility(View.INVISIBLE);
}
}
};
Toast.makeText(SampleActivity.this, "Broadcast Initialized", Toast.LENGTH_SHORT).show();
Toast.makeText(SampleActivity.this, "App is Created", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
super.onPause();
Toast.makeText(SampleActivity.this, "App has Paused", Toast.LENGTH_SHORT).show();
// Unregister your receiver
unregisterReceiver(breceiver);
Toast.makeText(SampleActivity.this, "Broadcast UnRegistered", Toast.LENGTH_SHORT).show();
}
}
This class extends AppCompatActivity (as usual). You can use this class to create an activity wherever you want your receiver to work with a few exception.
Use this class in other activities as follow:
public class MainActivity extends SampleActivity {
Button btnNext;
RelativeLayout Network_disconnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Make sure that you can setRelative before calling super.onCreate or you will get a NULL POINTER EXCEPTION
setRelative(Network_disconnection);
Toast.makeText(MainActivity.this, "Now Calling Supper", Toast.LENGTH_SHORT).show();
super.onCreate(savedInstanceState);
}
}
You can check this link to understand Activity life cycle:
https://developer.android.com/training/basics/activity-lifecycle/starting.html
or if in hurry, check this image:

BroadcastReceiver receives more Intents than sent

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.

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.

Finishing an Activity from a Broadcast Receiver

I have an Activity that I display as modeless when the phone rings (over the phone app). I would like to finish the Activity when either of the following events occur. The first is if I touch anywhere outside the Activity (this is not a problem), the second is if the ringing stops. I am listening for IDLE_STATE in the broadcast receiver but I am not sure on how to call the finish on the activity when I see it. The receiver is not registered by the activity but by the Manifest.xml
write the code in your receiving broadcast now this will send another broad cast with the intent named "com.hello.action"
Intent local = new Intent();
local.setAction("com.hello.action");
sendBroadcast(local);
Now catch this intent in the activity with you want to finish it and then call the super.finish() on the onReceive method of your receiver
like this
public class fileNamefilter extends Activity {
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter();
filter.addAction("com.hello.action");
registerReceiver(receiver, filter);
}
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
public void finish() {
super.finish();
};
}
this will finish the activity
What if you register another broadcast receiver from the activity. Then, when you want to kill it, send a broadcast message from the broadcast receiver that you mentioned.
I actually ended up adding a PhoneStateListener in the Activity to listen for IDLE_STATE.
After a long R&D over internet i have solved my problem. The below code is helpful if you start an activity from broadcast receiver and
clear all activity stack instance.
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
moveTaskToBack(true);
}
}
I used this code to solve my problem. finish is the method of Activity, so call Activity and context like:
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
Log.e(TAG, "Inside EXTRA_STATE_IDLE");
((Activity) arg0).finish();
}

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