Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android BroadcastReceiver for internet connection called twice

I am facing this issue for a while and noticed that a few other people also faced it, but I am not able to resolve it.

The Problem

I have a BroadcastReceiver, which keeps listening for the internet changes. So whenever the internet is connected or disconnected, I get the status in onReceive of the receiver.

The problem is it is always getting called twice. When I connect the debugger and have the breakpoint in the code, I can see it getting called twice but my code on status change executes. When the debugger is not connected, in that case my code on status change doesn't execute at all.

My Code

BroadcastReceiver file

public class ConnectivityReceiver
    extends BroadcastReceiver {

public static ConnectivityReceiverListener connectivityReceiverListener;

public ConnectivityReceiver() {
    super();
}

@Override
public void onReceive(Context context, Intent arg1) {
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();

    if (connectivityReceiverListener != null) {
        connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
    }
}

public static boolean isConnected() {
    ConnectivityManager
            cm = (ConnectivityManager) MyApplication.getInstance().getApplicationContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();
}


public interface ConnectivityReceiverListener {
    void onNetworkConnectionChanged(boolean isConnected);
}

}

Manifest intent action

<receiver
        android:name=".utils.ConnectivityReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>

here when I tried with only <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> in filter, then also it came to onRecieve twice. And when I tried with <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />, then I didn't come to onReceive at all.

BaseActivity

 @Override
public void onNetworkConnectionChanged(boolean isConnected) {
    setNetworkIndicator(isConnected); //THE CODE TO EXECUTE ON STATUS CHANGE
}

I tried the existing answers, and it didn't work for me.

like image 395
The Bat Avatar asked Apr 10 '18 08:04

The Bat


People also ask

What is BroadcastReceiver Android?

Android BroadcastReceiver is a dormant component of android that listens to system-wide broadcast events or intents. When any of these events occur it brings the application into action by either creating a status bar notification or performing a task.

What is BroadcastReceiver?

A broadcast receiver (receiver) is an Android component which allows you to register for system or application events. All registered receivers for an event are notified by the Android runtime once this event happens.

What is the life cycle of BroadcastReceiver?

A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent) . Once your code returns from this function, the system considers the object to be finished and no longer active.

What is the method name in BroadcastReceiver receive the message?

Receive SMS messages with a broadcast receiver. To receive SMS messages, use the onReceive() method of the BroadcastReceiver class. The Android framework sends out system broadcasts of events such as receiving an SMS message, containing intents that are meant to be received using a BroadcastReceiver.


2 Answers

My guess here is that the wifi receiver gets called twice because it gets called once for the enabling state, and once for the followup enabled state.

In the Documentation it is stated that:

Broadcast intent action indicating that Wi-Fi has been enabled, disabled, enabling, disabling, or unknown. One extra provides this state as an int. Another extra provides the previous state, if available.

You can check the values of EXTRA_WIFI_STATE and EXTRA_PREVIOUS_WIFI_STATE to verify if this is the case.

So in order to ignore the unwanted connecting/disconnecting states, you could update your onReceive() to the following:

@Override
public void onReceive(Context context, Intent arg1) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

    boolean isConnected = false;
    if (activeNetwork != null){

        if (activeNetwork.getState() == NetworkInfo.State.CONNECTING || activeNetwork.getState() == NetworkInfo.State.DISCONNECTING){
            return;
        }
        isConnected = activeNetwork.isConnected();
    }

    if (connectivityReceiverListener != null) {
        connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
    }

}
like image 112
W3hri Avatar answered Nov 15 '22 03:11

W3hri


Check this link

For Android 7 and above you need to register your receiver in your activity file not in the manifest file.

So in your activity's onCreate() add the following lines:

    myConnectivityReceiver = new ConnectivityReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(getResources().getString(R.string.action_connectivity_change));
    registerReceiver(myConnectivityReceiver,filter);

and in onDestroy()

  @Override
  protected void onDestroy() {
      unregisterReceiver(myConnectivityReceiver);
      super.onDestroy();
  }

define the intent action in strings.xml

<string name="action_connectivity_change">android.net.conn.CONNECTIVITY_CHANGE</string>
like image 31
nethra gowda Avatar answered Nov 15 '22 03:11

nethra gowda