0

I am developing an Android App that requires me to scan all available public wifi networks and connect to the one with highest signal strength. Can this be achieved is so HOW?

Right now my app just turns on wifi and connects to a saved network.

Ifrah
  • 209
  • 1
  • 5
  • 11

1 Answers1

6

First have a look at the official help:

http://developer.android.com/reference/android/net/wifi/WifiManager.html

then look around and found something like that:

How can I get Android Wifi Scan Results into a list?

ScanResult gives the rssi (level)that can be used to select the appropriate network:

http://developer.android.com/reference/android/net/wifi/ScanResult.html

Here's a simple code to scan:

WifiManager wifi= (WifiManager) getSystemService(Context.WIFI_SERVICE);

wifi.startScan();
// get list of the results in object format ( like an array )
List<ScanResult> results = wifi.getScanResults();`

// loop that goes through list
for (ScanResult result : results) {
  Toast.makeText(this, result.SSID + " " + result.level,
  Toast.LENGTH_SHORT).show();
}

Remember you need permsissions in your manifest.xml:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

UPDATE:

To create a network by SSID I use the following:

private boolean addNetworkAndActivate(ScanResult scanResult) {

    WifiConfiguration wc = null;

    List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();

    for (WifiConfiguration wifiConfiguration : configs) {
        try {
            if (wifiConfiguration.SSID.equals("\"" + scanResult.SSID + "\"")) {
                wc = wifiConfiguration;
                break;
            }
        } catch (Exception e) {

        }
    }

    // not configured, create new
    if (wc == null) {
        wc = new WifiConfiguration();

        ConfigurationSecuritiesV8 conf = new ConfigurationSecuritiesV8();
        conf.setupSecurity(wc, conf.getScanResultSecurity(scanResult), "7ej8e4jka9");
        wc.SSID = "\"" + scanResult.SSID + "\"";

        int res = wifiManager.addNetwork(wc);

        if (res == -1)
            return false;

        if (!wifiManager.saveConfiguration())
            return false;
    }

    boolean active = wifiManager.enableNetwork(wc.networkId, true);

    return active;
}

Classes:

public class ConfigurationSecuritiesV8 extends ConfigurationSecurities {

    static final int SECURITY_NONE = 0;
    static final int SECURITY_WEP = 1;
    static final int SECURITY_PSK = 2;
    static final int SECURITY_EAP = 3;

    enum PskType {
        UNKNOWN, WPA, WPA2, WPA_WPA2
    }

    private static final String TAG = "ConfigurationSecuritiesV14";

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

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

    @Override
    public String getWifiConfigurationSecurity(WifiConfiguration wifiConfig) {
        return String.valueOf(getSecurity(wifiConfig));
    }

    @Override
    public String getScanResultSecurity(ScanResult scanResult) {
        return String.valueOf(getSecurity(scanResult));
    }

    @Override
    public void setupSecurity(WifiConfiguration config, String security, String password) {
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();

        final int sec = security == null ? SECURITY_NONE : Integer.valueOf(security);
        final int passwordLen = password == null ? 0 : password.length();
        switch (sec) {
        case SECURITY_NONE:
            config.allowedKeyManagement.set(KeyMgmt.NONE);
            break;

        case SECURITY_WEP:
            config.allowedKeyManagement.set(KeyMgmt.NONE);
            config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
            config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
            if (passwordLen != 0) {
                // WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
                if ((passwordLen == 10 || passwordLen == 26 || passwordLen == 58) && password.matches("[0-9A-Fa-f]*")) {
                    config.wepKeys[0] = password;
                } else {
                    config.wepKeys[0] = '"' + password + '"';
                }
            }
            break;

        case SECURITY_PSK:
            config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
            if (passwordLen != 0) {
                if (password.matches("[0-9A-Fa-f]{64}")) {
                    config.preSharedKey = password;
                } else {
                    config.preSharedKey = '"' + password + '"';
                }
            }
            break;

        case SECURITY_EAP:
            config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
            config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
            // config.eap.setValue((String)
            // mEapMethodSpinner.getSelectedItem());
            //
            // config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition()
            // == 0) ? "" :
            // "auth=" + mPhase2Spinner.getSelectedItem());
            // config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition()
            // == 0) ? "" :
            // KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
            // (String) mEapCaCertSpinner.getSelectedItem());
            // config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition()
            // == 0) ?
            // "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
            // (String) mEapUserCertSpinner.getSelectedItem());
            // config.private_key.setValue((mEapUserCertSpinner.getSelectedItemPosition()
            // == 0) ?
            // "" : KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
            // (String) mEapUserCertSpinner.getSelectedItem());
            // config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
            // mEapIdentityView.getText().toString());
            // config.anonymous_identity.setValue((mEapAnonymousView.length() ==
            // 0) ? "" :
            // mEapAnonymousView.getText().toString());
            // if (mPasswordView.length() != 0) {
            // config.password.setValue(mPasswordView.getText().toString());
            // }
            break;

        default:
            LogBridge.d(TAG, "Invalid security type: " + sec);
        }

        // config.proxySettings = mProxySettings;
        // config.ipAssignment = mIpAssignment;
        // config.linkProperties = new LinkProperties(mLinkProperties);

    }

    private static PskType getPskType(ScanResult result) {
        boolean wpa = result.capabilities.contains("WPA-PSK");
        boolean wpa2 = result.capabilities.contains("WPA2-PSK");
        if (wpa2 && wpa) {
            return PskType.WPA_WPA2;
        } else if (wpa2) {
            return PskType.WPA2;
        } else if (wpa) {
            return PskType.WPA;
        } else {
            LogBridge.d(TAG, "Received abnormal flag string: " + result.capabilities);
            return PskType.UNKNOWN;
        }
    }

    @Override
    public String getDisplaySecirityString(final ScanResult scanResult) {
        final int security = getSecurity(scanResult);
        if (security == SECURITY_PSK) {
            switch (getPskType(scanResult)) {
            case WPA:
                return "WPA";
            case WPA_WPA2:
            case WPA2:
                return "WPA2";
            default:
                return "?";
            }
        } else {
            switch (security) {
            case SECURITY_NONE:
                return "OPEN";
            case SECURITY_WEP:
                return "WEP";
            case SECURITY_EAP:
                return "EAP";
            }
        }

        return "?";
    }

    @Override
    public boolean isOpenNetwork(String security) {
        return String.valueOf(SECURITY_NONE).equals(security);
    }
}

And

public abstract class ConfigurationSecurities {
    /**
     * @return The security of a given {@link WifiConfiguration}.
     */
    public abstract String getWifiConfigurationSecurity(WifiConfiguration wifiConfig);

    /**
     * @return The security of a given {@link ScanResult}.
     */
    public abstract String getScanResultSecurity(ScanResult scanResult);

    /**
     * Fill in the security fields of WifiConfiguration config.
     * 
     * @param config
     *            The object to fill.
     * @param security
     *            If is OPEN, password is ignored.
     * @param password
     *            Password of the network if security is not OPEN.
     */
    public abstract void setupSecurity(WifiConfiguration config, String security, final String password);

    public abstract String getDisplaySecirityString(final ScanResult scanResult);

    public abstract boolean isOpenNetwork(final String security);

    public static ConfigurationSecurities newInstance() {
//      if (Version.SDK < 8) {
//          return new ConfigurationSecuritiesOld();
//      } else {
            return new ConfigurationSecuritiesV8();
//      }
    }

}
Community
  • 1
  • 1
Seraphim's
  • 12,559
  • 20
  • 88
  • 129
  • Thanx Seraphim .. BSSID could be used to distinguish between public networks.. But How could i use the result.level values to choose the one with highest strength??? – Ifrah Sep 26 '13 at 10:57
  • Are you asking me how to sort a array of signed integer? ;) – Seraphim's Sep 26 '13 at 10:59
  • Collections.sort( publicnetworks, new Comparator() { @Override public int compare(ScanResult lhs, ScanResult rhs) { return (lhs.level bestnetwork = new ArrayList(1); bestnetwork.add(publicnetworks.get(i)); – Ifrah Sep 26 '13 at 11:48
  • i managed to develop this ... but how to actually acquire the lock on ''bestnetwork'? – Ifrah Sep 26 '13 at 11:49
  • What do you mean with "lock"? – Seraphim's Sep 26 '13 at 11:58
  • When you kno the ssid e the bssid you can manage to create a new wifi connection. Whait 2 minute and I will update my answer. – Seraphim's Sep 26 '13 at 12:04
  • http://stackoverflow.com/questions/19028358/deleting-all-videos-in-android-gallery-loop-not-working ... could you kindly answer this question as well .. – Ifrah Sep 26 '13 at 12:36
  • Yes thanks a lot... i appreciate the effort you put into your answers.. but could you please cut it down to connecting to a public server only ..??i would appreciate that. – Ifrah Sep 26 '13 at 14:50
  • What do you mean with "connect to a public server only". Anyway if I response to your question please accept the answer and (I'll appreciato) upvote it. Open a new question and be more precise on what you're asking for. Thanks. – Seraphim's Sep 26 '13 at 15:56
  • http://kmansoft.com/2010/04/08/adding-wifi-networks-to-known-list/ ... got the answer here :) – Ifrah Sep 26 '13 at 16:32
  • @Seraphim's can you please help me with my problem.. I used youre code, but stucked at this error - `Error:(151, 43) error: cannot find symbol variable wifiManager` I'm working in Android Studio 1.3.2... How I can fix this error? Tried clean build and rebuild project, but it doesnot helped =( – vladimir Sep 15 '15 at 12:44
  • 1
    @vladimir using context (an Activity, ...) you get wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); – Seraphim's Sep 15 '15 at 12:46
  • @Seraphim's but if I'm using Service? – vladimir Sep 15 '15 at 12:52
  • @vladimir use context = getApplicationContext() – Seraphim's Sep 15 '15 at 12:54