android: Determine security type of wifi networks in range (without connecting to them)-ThrowExceptions

Exception or error:

I can enumerate all wifi networks in range (using startScan + SCAN_RESULTS_AVAILABLE_ACTION + getScanResults) and get their SSID and BSSID values, but I can’t figure out how to determine the security type of each network.

In my main object:

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    registerReceiver(scanReceiver, intentFilter);
    ((WifiManager)getSystemService(Context.WIFI_SERVICE)).startScan();

In my scanReceiver object:

public void onReceive(Context c, Intent intent) {
    if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())){
        mainObject.scanComplete();
    }
}

And again in my main object:

public void scanComplete()
{
    List<ScanResult> networkList = ((WifiManager)getSystemService.(Context.WIFI_SERVICE)).getScanResults();
    for (ScanResult network : networkList)
    {
        <do stuff>
    }
}

The code works insofar that scanComplete eventually gets called, and I can successfully enumerate all nearby wifi networks and get their SSID and BSSID, but I can’t figure out how to determine their security type.

Is there a way to do this?

Thanks in advance.

How to solve:

I think you can find it in the source code of Settings.apk.

First you should call wifiManager.getConfiguredNetworks() or wifiManager.getScanResults(),
then use the two methods below: (find them in AccessPoint class "com.android.settings.wifi"):

static int getSecurity(WifiConfiguration config) {
    if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
        return SECURITY_PSK;
    }
    if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
            config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
        return SECURITY_EAP;
    }
    return (config.wepKeys[0] != null) ? SECURITY_WEP : SECURITY_NONE;
}

static int getSecurity(ScanResult result) {
    if (result.capabilities.contains("WEP")) {
        return SECURITY_WEP;
    } else if (result.capabilities.contains("PSK")) {
        return SECURITY_PSK;
    } else if (result.capabilities.contains("EAP")) {
        return SECURITY_EAP;
    }
    return SECURITY_NONE;
}

Hope this is helpful.

###

You need to parse the ScanResult’s capabilities string in the scanComplete method. According to the Android developer documentation, :

ScanResult.capabilities describes the authentication, key management, and
encryption schemes supported by the access point.

You might be able to make use of — or at the very least use as an example — the static helper methods available in the AccessPointState class.

###

Thanks very much,… you made my day…

I have something to add here. Without scanning for the networks, one can get the currently connected wifi configuration information (specially encryption and key management) as follows,

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
List<ScanResult> networkList = wifi.getScanResults();
if (networkList != null) {
    for (ScanResult network : networkList)
    {
        String Capabilities =  network.capabilities;        
        Log.w (TAG, network.SSID + " capabilities : " + Capabilities);
    }
}

###

The security type of each network is in the Capabilities column of the scan results.

So to get the security type for you, add this to your part of your code.

public void scanComplete()
{
    List<ScanResult> networkList = ((WifiManager)getSystemService.(Context.WIFI_SERVICE)).getScanResults();
    for (ScanResult network : networkList)
    {
        String Capabilities =  network.capabilities;

        //Then you could add some code to check for a specific security type. 
        if(Capabilities.contains("WPA"))
     {
          // We know there is WPA encryption
         }
        else if(Capabilities.contains("WEP"))
         {
         // We know there is WEP encryption
         }
        else
         { 
         // Another type of security scheme, open wifi, captive portal, etc..
         }

    }
}

Anyways, here’s some quick source code. I would fully recomment Ayj’s answer though, as it is an exceptional response and more complete.

Leave a Reply

Your email address will not be published. Required fields are marked *