Android - How to scan Access Points and select strongest signal?
Asked Answered
E

2

8

I am currently trying to write a class in Android that will Scan for access points, calculate which access point has the best signal and then connect to that access point.

So the application will be able to scan on the move and attach to new access points on the go.

I have the scanning and calculation of the best signal working.

But when it comes to attaching to the best access point I am having trouble.

It appears that enableNetwork(netid, othersTrueFalse) is the only method for attaching to an Access point but this causes problems as from my Scan Results I am not able to get the id of the access point with the strongest signal.

This is my code:


public void doWifiScan(){

  scanTask = new TimerTask() {
  public void run() {
      handler.post(new Runnable() {
          public void run() {
               sResults = wifiManager.scan(getBaseContext()); 
               if(sResults!=null)
               Log.d("TIMER", "sResults count" + sResults.size());
               ScanResult scan = wifiManager.calculateBestAP(sResults);
               wifiManager.addNewAccessPoint(scan);
           }
       });
    }};

    t.schedule(scanTask, 3000, 30000); 
}

public ScanResult calculateBestAP(List<ScanResult> sResults){

     ScanResult bestSignal = null;
        for (ScanResult result : sResults) {
          if (bestSignal == null
              || WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
            bestSignal = result;
        }

        String message = String.format("%s networks found. %s is the strongest. %s is the bsid",
                sResults.size(), bestSignal.SSID, bestSignal.BSSID);

        Log.d("sResult", message);
        return bestSignal;
}

public void addNewAccessPoint(ScanResult scanResult){

    WifiConfiguration wc = new WifiConfiguration();
    wc.SSID = '\"' + scanResult.SSID + '\"';
    //wc.preSharedKey  = "\"password\"";
    wc.hiddenSSID = true;
    wc.status = WifiConfiguration.Status.ENABLED;        
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    int res = mainWifi.addNetwork(wc);
    Log.d("WifiPreference", "add Network returned " + res );
    boolean b = mainWifi.enableNetwork(res, false);        
    Log.d("WifiPreference", "enableNetwork returned " + b );

}

When I try to use addNewAccessPoint(ScanResult scanResult) it just adds another AP to the list in the settings application with the same name as the one with the best signal, so I end up with loads of duplicates and not actually attaching to them.

Can anyone point me in the direction of a better solution?

Eschatology answered 13/5, 2010 at 14:41 Comment(0)
C
3

Simply change

boolean b = mainWifi.enableNetwork(res, false);

to

boolean b = mainWifi.enableNetwork(res, true); 
Corydalis answered 25/1, 2011 at 0:8 Comment(0)
G
0

More to the point of your question. First you are determining the scan result with the best signal strength. Once you have that, you should also get the list of wifi configurations already on the device and ensure that the scan result with the strongest signal is not already configured with the device. If it is, simply enable it, if not, create a new one as you are. This will help you avoid duplicate configs.

private int findExistingNetworkConfig(String ssid) {
    if (ssid != null && !ssid.isEmpty()) {
        WifiManager wifiManager = (WifiManager) mContextRef.get()
                .getSystemService(Context.WIFI_SERVICE);
        for (WifiConfiguration wifiConfig : wifiManager
                .getConfiguredNetworks()) {
            if (ssid.equals(wifiConfig.SSID)) {
                return wifiConfig.networkId;
            }
        }
    }
    // Didn't find a matching network ssid
    return -1;
}

And yes, be sure to use the 'true' parameter when enabling networks. This will help ensure you connect to the network you intend.

wifiManager.enableNetwork(mNetID, true);
Garlaand answered 27/2, 2014 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.