Connectivity_Action Intent Received Twice When Wifi Connected

CONNECTIVITY_ACTION intent received twice when Wifi connected

NOTE: For a recent, up-to-date answer, see this one below!

After a lot of googling and debugging, I believe this is the correct way to determine if Wifi has connected or disconnected.

The onReceive() method in the BroadcastReceiver:

public void onReceive(final Context context, final Intent intent) {

if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo networkInfo =
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(networkInfo.isConnected()) {
// Wifi is connected
Log.d("Inetify", "Wifi is connected: " + String.valueOf(networkInfo));
}
} else if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo =
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
! networkInfo.isConnected()) {
// Wifi is disconnected
Log.d("Inetify", "Wifi is disconnected: " + String.valueOf(networkInfo));
}
}
}

Together with the following receiver element in AndroidManifest.xml

<receiver android:name="ConnectivityActionReceiver"
android:enabled="true" android:label="ConnectivityActionReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
</receiver>

Some explanation:

  • When only considering ConnectivityManager.CONNECTIVITY_ACTION, I always get two intents containing identical NetworkInfo instances (both getType() == TYPE_WIFI and isConnected() == true) when Wifi connects - the issue described in this question.

  • When only using WifiManager.NETWORK_STATE_CHANGED_ACTION, there is no intent broadcasted when Wifi disconnects, but two intents containing different NetworkInfo instances, allowing to determine one event when Wifi is connected.

NOTE: I've received one single crash report (NPE) where the intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO) returned null. So, even if it seems to be extremely rare to happen, it might be a good idea to add a null check.

Cheers,
Torsten

Android BroadcastReceiver for internet connection called twice

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>

Detect when connected/disconntected to Wi-Fi

nothing happens. What am I doing wrong?

As far as I can see you have not declared the BroadcastReceiver, adding permission alone would not trigger your broadcast receiver.

My solution is based on declaring it via manifest, but that said your problem is I can not see you have declared broadcaster class in your code, so you can chose declare it in manifest or in your code.

So try to declare it and it should works. I have tested your code with both declaration and it works:

<receiver android:name=".WifiScanReceiver">
<intent-filter>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
</receiver>

Or declare it programmatically new WifiScanReceiver() in onCreate method:

final IntentFilter filters = new IntentFilter();
filters.addAction("android.net.wifi.STATE_CHANGE");
super.registerReceiver(new WifiScanReceiver(), filters);

You will need this also (reference) in your WifiScanReceiver:

public void onReceive(Context context, Intent intent) {

ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

if (isWiFi) {
Log.i("TAG", "trigged");
}
}

Broadcast Receiver get notified when connecting to another wifi network

Please try this solution,

BroadcastReceiver broadcastReceiver = new WifiBroadcastReceiver();

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
context.registerReceiver(broadcastReceiver, intentFilter);

You need to check the MAC addresses of the routers to check if there is a change in the Wifi connection.

public class WifiBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION .equals(action)) {
SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
if (SupplicantState.isValidState(state)
&& state == SupplicantState.COMPLETED) {
boolean changed = checkWifiChanged();
}
}
}

/** Detect if WiFi is changed. */
private boolean checkWifiChanged() {
boolean changed = false;

// You can store the previous MAC address in Shared Preferences and fetch it here
String previousMacAddress = getPreviousMacAddress();

WifiManager wifiManager =
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);

WifiInfo wifi = wifiManager.getConnectionInfo();
if (wifi != null) {
// Get current router MAC address
String bssid = wifi.getBSSID();
changed = !previousMacAddress.equals(bssid);
}

return changed;
}
}

You can store the previous MAC address in a database or Shared Preference and check the new connected MAC address with the previous one. If they are different, then the WiFi connection has changed otherwise not.

OnReceive OnReceive firing twice

I do not know if what I say is in Xamarin's documentation, but this happens because you're probably using the class attribute BroadcastReceiver.

In my tests, to put this attribute in the class is no longer necessary to register the Receiver class by RegisterReceiver method or the Android Manifest file of the application.

Try the following example, using the application template blank Xamarin for Android:

BatrianoReceiver.cs

//Comment this line if you register the Receiver class with RegisterReceiver method or in the Android Manifest file
[BroadcastReceiver(Label = "Batriano custom Receiver")]
[IntentFilter(new string[] { "com.batressc.batriano.CUSTOM_RECEIVER" })]
public class BatrianoReceiver : BroadcastReceiver {
public override void OnReceive(Context context, Intent intent) {
string extraData = intent.GetStringExtra("BatrianoData");
if (extraData != null) Log.Info("batriano", extraData);
else Log.Warn("batriano", "No se encontraron datos");
}
}

MainActivity.cs

[Activity(Label = "Uso Receivers", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity {
private BatrianoReceiver receiver;

protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += (sender, e) => {
Intent batriano = new Intent();
batriano.SetAction("com.batressc.batriano.CUSTOM_RECEIVER");
batriano.PutExtra("BatrianoData", string.Format("{0}-{1}", Guid.NewGuid(), DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff tt")));
SendBroadcast(batriano);
};
//Uncomment this line if you comment [BroadcastReceiver] attribute and register the receiver class with RegisterReceiver method of in Android Manifest file
//Register();
}

protected override void OnStop() {
base.OnStop();
//Uncomment this line if you comment [BroadcastReceiver] attribute and register the receiver class with RegisterReceiver method of in Android Manifest file
//Unregister();
}

protected override void OnResume() {
base.OnResume();
//Uncomment this line if you comment [BroadcastReceiver] attribute and register the receiver class with RegisterReceiver method of in Android Manifest file
//Register();
}

private void Unregister() {
if (receiver != null) {
UnregisterReceiver(receiver);
receiver = null;
}
}

private void Register() {
if (receiver == null) {
receiver = new BatrianoReceiver();
RegisterReceiver(receiver, new IntentFilter("com.batressc.batriano.CUSTOM_RECEIVER"));
}
}
}


Related Topics



Leave a reply



Submit