Home » Android » android – Broadcast Receiver calles twice

android – Broadcast Receiver calles twice

Posted by: admin May 14, 2020 Leave a comment

Questions:

Trying to check Internet connection in my app.
There is a code of my manifest:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <receiver android:name=".MyReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
        </intent-filter>
    </receiver>

And there is a handle class:

public class MyReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction() != null && intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE"));
    {
        Log.d("myLogs", "Network connectivity change");
        if (intent.getExtras() != null) {
            NetworkInfo ni = (NetworkInfo) intent.getExtras().get(
                    ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i("myLogs", "Network " + ni.getTypeName() + " connected");
            }
        }
        if (intent.getExtras().getBoolean(
                ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("myLogs", "There's no network connectivity");
        }
    }
}

}

In my Logcat i get a picture like a:

04-11 23:24:48.021: D/myLogs(10261): Network connectivity change
04-11 23:24:48.021: I/myLogs(10261): Network WIFI connected
04-11 23:24:48.202: D/myLogs(10261): Network connectivity change
04-11 23:24:48.202: I/myLogs(10261): Network WIFI connected

So, receiver called twice. Why? There is some problem with all types of connections.

How to&Answers:

Assuming you get the connected message when the wifi is connected, I would guess the first one is the correct one and the other 2 are just echoes for some reason.

To know that the message has been called, you could have a static boolean that gets toggled between connect and disconnect and only call your sub-routines when you receive a connection and the boolean is true. Something like:

public class ConnectionChangeReceiver extends BroadcastReceiver {
    private static boolean firstConnect = true;

    @Override
    public void onReceive(Context context, Intent intent) {
        final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null) {
            if(firstConnect) { 
                // do subroutines here
                firstConnect = false;
            }
        }
        else {
            firstConnect= true;
        }
    }
}

Note

There are two things you need to watch for. First – store “firstConnect” somewhere, for example in shared preferences, and second is when you change from 3G to WiFi, there is no actual disconnect, so It’s better to handle 3G and WiFi events separately

Answer:

You may also need to check to see if the intent being received is one of the Sticky events by checking isStickyBroadcast in your reciever. If that is true, then you may ignore it, and continue on. You get sticky broadcasts as soon as the receiver is registered.

http://developer.android.com/reference/android/content/BroadcastReceiver.html#isInitialStickyBroadcast%28%29

Answer:

Explained in the docs:

Changes to a device’s connectivity can be very frequent—this broadcast is triggered every time you move between mobile data and Wi-Fi. As a result, it’s good practice to monitor this broadcast only when you’ve previously suspended updates or downloads in order to resume them. It’s generally sufficient to simply check for Internet connectivity before beginning an update and, should there be none, suspend further updates until connectivity is restored.”

Edit:
Forgot to add…a broadcast receiver only to know if the device is connected is a bit of an hoverhead. From the same docs:

ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;