简体   繁体   中英

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.

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);
    }

}

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>

Usually,when on Receive is called twice broadcast receiver called twice.So please check you are registering the broadcast in 2 locations? If yes then Please register your broadcast only in resume or create and also unregistered it onPause() method of activity.

For Example Register Broadcast receiver,

LocalBroadcastManager.getInstance(this).registerReceiver(myLocalBroadcastManager, new IntentFilter(Constant.CONNECTIVITY_CHANGE));

Unregistered Broadcast Receiver like:-

LocalBroadcastManager.getInstance(this).unregisterReceiver(myLocalBroadcastManager);

I hope it helps you.

You should check the intent action in the onReceive callback:

String action = arg1.getAction();
if (action != null && action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
    // do your task here.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM