SeeNoWeevil
SeeNoWeevil

Reputation: 2619

Android - Correct way to detect disconnecting from a particular wifi ssid?

I've seen a couple of BroadcastReciever examples to detect wifi disconnects but none of them seem to work correctly (triggering twice for each disconnect for example) and none mention checking against an ssid, is this even possible?

So just to clarify, I want to detect disconnection from a particular ssid. An actual disconnect and not wifi being disabled on the device.

Thanks

EDIT: Re-opening as nothing works on both the devices we have to test.

Upvotes: 4

Views: 8716

Answers (4)

Yukun
Yukun

Reputation: 13

I got the same problem in some custom roms. I used "android.net.wifi.STATE_CHANGE" to listen the network change. In the receiver, I used "(NetworkInfo)intent.getParcelableExtra("networkInfo")).getState()" to get the network state. There are three states: DISCONNECTED, CONNECTING, CONNECTED. You can use DISCONNECTED to detect if the network is disconnected.

Please let me know if it works in your situation(HTC One X (4.1)).

Upvotes: 0

SeeNoWeevil
SeeNoWeevil

Reputation: 2619

NETWORK_STATE_CHANGED_ACTION was the answer in the end. The device having the problem registering this event started working when another app (which would also be listening for similar events) was uninstalled! No idea how or why an app could block events registering with another app. The final solution ended up being;

    String action = intent.getAction();

    if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION))
    {
        WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
        NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        NetworkInfo.State state = networkInfo.getState();

        if(state == NetworkInfo.State.CONNECTED)
        {
            String connectingToSsid = manager.getConnectionInfo().getSSID().replace("\"", "");
            WifiStateHistory.recordConnectedSsid(connectingToSsid);
//connected
        }

        if(state == NetworkInfo.State.DISCONNECTED)
        {
            if(manager.isWifiEnabled())
            {
                String disconnectedFromSsid = WifiStateHistory.getLastConnectedSsid();
//disconnected
            }
        }
    }

Upvotes: 8

SeeNoWeevil
SeeNoWeevil

Reputation: 2619

My code to detect (and rebroadcast) connections and disconnects (not by disabling wifi) and including the SSID as an extra is as follows. Most of what I've read suggested using SUPPLICANT_CONNECTION_CHANGE_ACTION but this just did not work correctly, it would seemingly only fire when disabling/enabling wifi on my device (Nexus 4) and not during connections. The only problem is on first run of the app as it won't record the current ssid so doesn't know what the ssid of the network that has just been connected. Any ideas around this?

public class EventMapper extends BroadcastReceiver
{
    private static String lastConnectedSsid = "";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION))
        {
            SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);

            if(state == SupplicantState.COMPLETED)
            {
                WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);

                lastConnectedSsid = manager.getConnectionInfo().getSSID().replace("\"", "");

                Intent newIntent = new Intent();            
                newIntent.setAction(Event.App_Event_WifiConnected.name());
                newIntent.putExtra("App_Events_SSID", lastConnectedSsid);

                context.sendBroadcast(newIntent);
            }

            if(state == SupplicantState.DISCONNECTED)
            {
                boolean wifiEnabled = ((WifiManager)context.getSystemService(Context.WIFI_SERVICE)).isWifiEnabled();

                if(wifiEnabled)
                {
                    Intent newIntent = new Intent();            
                    newIntent.setAction(Event.App_Event_WifiDisconnected.name());
                    newIntent.putExtra("App_Events_SSID", lastConnectedSsid);

                    context.sendBroadcast(newIntent);   
                }
            }
        }
    }
}

Upvotes: 0

pinxue
pinxue

Reputation: 1746

Are you sure there are twice notification for same state? There are always two phase of disconnection:

WifiManager.WIFI_STATE_DISABLING

WifiManager.WIFI_STATE_DISABLED

Upvotes: 0

Related Questions