I have created the one receiver inside an Activity for when internet is connected auto calling web service.
Code like
//Create receiver for while network will come auto call webservice
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (!noConnectivity) {
bar.setVisibility(View.VISIBLE);
callAuthorizeWebservice();
} else {
bar.setVisibility(View.INVISIBLE);
Toast.makeText(SplashScreenActivity.this, "Check Your Internet connection", Toast.LENGTH_LONG).show();
}
}
};
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(mConnReceiver);
}
#Override
protected void onStart() {
super.onStart();
this.registerReceiver(this.mConnReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
When I open that Activity the onReceive() is method called everytime.
How to avoid calling it the first time (when opening that Activity)?
The broadcast is sent when you register for the first time(cf sticky broadcast), a solution is to use isInitialStickyBroadcast in the onReceive callback of your BroadcastReceiver to know if you are actually proceeding a sticky broadcast and act accordingly (BroadcastReceiver : isInitialStickyBroadcast)
Related
I have a broadcast receiver that gets triggered on geofencing events and either "clocks in" or "clocks out" with the server. If my application's "Attendance" activity is already open I would like it to display the clocking status change but I don't want the Broadcast Receiver to start the activity if it's not open - in other words display the change "live" while the activity is open only.
The way I imagine doing this is with the Broadcast Receiver sending an Intent to the activity but name "startActivity()" doesn't sound encouraging unless there are any special flags I can pass to prevent starting an Activity that isn't already open - I can't seem to find any.
The other option would be to constantly poll the value while the activity is open but it doesn't seem optimal so I would only use it if there wasn't another way and I can't think of a reason why it couldn't be possible with Intents.
There are several different ways to accomplish the same task. One is registering a listener like the following example:
MainActivity
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Receiver.setOnReceiveListener(new Receiver.OnReceiveListener() {
public void onReceive(Context Context, Intent intent)
{
//Do something.
}
});
}
#Override
protected void onDestroy()
{
super.onDestroy();
Receiver.setOnReceiveListener(null);
}
}
Receiver
public class Receiver extends BroadcastReceiver
{
private static OnReceiveListener static_listener;
public static abstract interface OnReceiveListener
{
public void onReceive(Context context, Intent intent);
}
public static void setOnReceiveListener(OnReceiveListener listener)
{
static_listener = listener;
}
#Override
public final void onReceive(Context context, Intent intent)
{
if(static_listener != null) {
static_listener.onReceive(context, intent);
}
}
}
Just have your BroadcastReceiver send a broadcast Intent. Your Activity should register a listener from this broadcast Intent and if it gets triggered, it can update the UI.
Here's an example:
Declare a private member variable in your Activity:
private BroadcastReceiver receiver;
In Activity.onCreate(), register the BroadcastReceiver:
IntentFilter filter = new IntentFilter();
filter.addAction("my.package.name.CLOCK_STATUS_CHANGE");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Here you can update the UI ...
}
};
registerReceiver(receiver, filter);
And in onDestroy() you can unregister it (probably not necessary, but cleaner):
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
In your BroadcastReceiver that detects the geofencing event, you should create and send a broadcast Intent:
Intent broadcastIntent = new Intent("my.package.name.CLOCK_STATUS_CHANGE");
sendBroadcast(broadcastIntent);
I keep getting the following error:
> java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.BroadcastReceiver.onReceive(android.content.Context, android.content.Intent)' on a null object reference
When I try to receive a broadcast from my service class.
Service:
#Override
public void onDestroy(){
super.onDestroy();
Intent intent = new Intent("UpdateLocation");
intent.putExtra("Location",journ);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
That is the code to send the broadcast sending a custom object(Journ) to my main activity.
Main:
#Override
protected void onCreate(Bundle savedInstanceState)
LocalBroadcastManager.getInstance(this).registerReceiver(
mReceiver, new IntentFilter("UpdateLocation"));
//Listen for service to send location data
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
temp= intent.getExtras().getParcelable("Location");
}
};
}
#Override
public void onPause() {
if (!tracking) {
finish();
}
//Run service in background to keep track of location
startService(new Intent(this, locationService.class));
super.onPause();
}
#Override
public void onResume() {
if (!tracking) {
return;
}
if (mGoogleApiClient != null) {
//Reconnect to google maps
mGoogleApiClient.reconnect();
}
stopService(new Intent(this, locationService.class));
super.onResume();
}
I am not sure how to go about doing this, I am trying to pass the object from my service class which runs when my app is in the background and when it resumes the service should stop and sends the data it gathered to my main activity.
This, however, doesn't work, any ideas?
In case people were wondering my on create method does contain more code, but I didn't think it necessary to include.
In onCreate mReciever is a null object (if you didn't assign it earlier), so you should assign it before registering a receiver.
Change this part:
if (mReceiver == null) {
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
temp= intent.getExtras().getParcelable("Location");
}
};
}
//Listen for service to send location data
LocalBroadcastManager.getInstance(this)
.registerReceiver(mReceiver, new IntentFilter("UpdateLocation"));
Iam working with chat application.
In onPause() and in onResume() I registered the receiver.
I cannot unregister receiver in onPause() because in receiver Iam checking for the network connection
In onPause and onResume I have to monitor the network
Then Iam in confusion that where to unregister receiver?
Could anyone please help me.
protected void onPause(){
backfacekey=1;
//unregisterReceiver(mConnReceiver);
super.onPause();
registerReceiver(mFacebookReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
protected void onResume(){
backfacekey=0;
super.onResume();
registerReceiver(mFacebookReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
private BroadcastReceiver mFacebookReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {
Toast.makeText(getApplicationContext(), "Network disconnected",Toast.LENGTH_LONG).show();
}
key=2;
}
if (info.getState().equals(NetworkInfo.State.CONNECTED)) {
if(key==2){
Toast.makeText(getApplicationContext(), "Network connected ",Toast.LENGTH_LONG).show();
key=0;
}
}
};
You can unregister your receiver in the onStop() or onDestroy() method.
I need some way to detect when the network connection has been lost.
So a switch between mobile and wifi doesn't really matter it's just to detect at runtime when the connection has been lost.
I now have found some code which works fine for me.
public class ConnectivityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(ConnectivityReceiver.class.getSimpleName(), "action: "
+ intent.getAction());
}
}
I want to check inside the onReceive() method wheter or not a connection is still available or not.
The thing is, that I want to show a message to the user, if it has been lost. So what's the best way of passing back to my Activity, that the connection has been lost?
If you want to track network connection state only when activity is on screen you can place your ConnectivityReceiver as inner nested class in Activity. In this case you should register it in onResume method and unregister it in onPause. It will look like this:
public class MyActivity extends Activity {
private class ConnectivityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(ConnectivityReceiver.class.getSimpleName(), "action: "
+ intent.getAction());
}
}
private final BroadcastReceiver receiver = new ConnectivityReceiver();
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(receiver, filter);
}
}
You can have an inner Class which extends BroadcastReceiver and you can dynamically register it. From the innterclass(precisely onRecieve() method) you can access your Activity.
I want to dynamically register and unregister my receiver class with the broadcast:
"android.net.wifi.STATE_CHANGE"
This works very well if I do this in the manifest. But this makes it static. I want to do it dynamically in the activity class. What is its correspondent command in the activity class?
This is what my code is...
and I am getting a problem because of registering and unregistering(multiple times) my receiver(which is starting a service).
public class startScreen extends Activity {
/** Called when the activity is first created. */
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.example.MyService");
context.startService(serviceIntent);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.initial);
final IntentFilter filter = new IntentFilter();
filter.addAction("android.net.wifi.STATE_CHANGE");
Button button = (Button) findViewById(R.id.button1);
final ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton1);
try {
...some code...
if (bool == true) {
toggleButton.setChecked(true);
this.registerReceiver(receiver, filter);
} else
toggleButton.setChecked(false);
} catch (Exception e) {
Log.e("Error", "Database", e);
} finally {
...
}
toggleButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if ((toggleButton.isChecked())) {
getBaseContext().registerReceiver(receiver, filter);
} else {
if (receiver != null) {
getBaseContext().unregisterReceiver(receiver);
receiver = null;
}
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (bool == true) {
if (receiver == null)
this.registerReceiver(receiver, filter);
}
}
#Override
protected void onPause() {
super.onPause();
if (receiver != null) {
this.unregisterReceiver(receiver);
receiver = null;
}
}
}
The LocalBroadcastManager class is used to register for and send broadcasts of Intents to local objects within your process. This is faster and more secure as your events don't leave your application.
The following example shows an activity which registers for a customer event called my-event.
#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();
}
// This method is assigned to button in the layout
// via the onClick property
public void onClick(View view) {
sendMessage();
}
// Send an Intent with an action named "my-event".
private void sendMessage() {
Intent intent = new Intent("my-event");
// add data
intent.putExtra("message", "data");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
use the below methods to register/unregister your receiver:
registerReceiver(BroadcastReceiver receiver, new IntentFilter("android.net.wifi.STATE_CHANGE"));
unregisterReceiver(BroadcastReceiver receiver);
For reference have a look at this
Don't add dynamic broadcast receiver in onReceive on broadcast file. Add it on first activity or main activity of your application. If you needed it only when your application is open. But if you need it always received response just added it on manifest file
Register dynamic broadcast receiver on main activity
MyReceiver reciver;
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
intentFilter.addAction("android.net.wifi.STATE_CHANGE");
reciver = new MyReceiver();
registerReceiver(reciver, intentFilter);
}
Unregister that broadcast receiver on activity stop or closed
#Override
protected void onStop() {
super.onStop();
unregisterReceiver(reciver);
}
Perhaps I'm a bit too late, but the problem lies on the fact that you are setting the receiver = null in your onPause method, and then never setting it again. You are also trying to register it in your onResume method but only if it is null, which makes no sense too.
You should change the logic where you set/test the null value of the receiver, to instead just use a boolean variable to keep track of the receiver status (if it's registered or not).
public void registerBroadcastReceiver(View view) {
this.registerReceiver(broadCastReceiver, new IntentFilter(
"android.intent.action.TIME_TICK"));
}
public void unregisterBroadcastReceiver(View view) {
this.unregisterReceiver(broadCastReceiver);
}