4

i'm trying to make an app that can create a list of available wifi access point. here's part of the code i used:

x = new BroadcastReceiver()
        {
            @Override
            public void onReceive(Context c, Intent intent) 
            {
                results = wifi.getScanResults();
                size = results.size();
                if (results != null) {
                    for (int i=0; i<size; i++){
                        ScanResult scanresult = wifi.getScanResults().get(i);
                        String ssid = scanresult.SSID;
                        int rssi = scanresult.level;
                        String rssiString = String.valueOf(rssi);
                        textStatus.append(ssid + "," + rssiString);
                        textStatus.append("\n");
                    }
                    unregisterReceiver(x); //stops the continuous scan
                    textState.setText("Scanning complete!");
                } else {
                    unregisterReceiver(x); 
                    textState.setText("Nothing is found. Please make sure you are under any wifi coverage");
                }
            }
        };

both textStatus and textState is a TextView. i can get this to work but sometimes the result shows duplicate SSID but with different signal level, in a single scan. there might be 3-4 same SSIDs but with different signal level.

is it really different SSIDs and what differs them? can anyone explain?

randms26
  • 137
  • 1
  • 6
  • 16
  • For passersby : change `size = results.size(); if (results != null) {` to `if (results != null) { size = results.size();` – Mr_and_Mrs_D Nov 29 '13 at 02:03

3 Answers3

10

Are you having several router modems for the same network? For example: A company has a big wireless network with multiple router modems installed in several places so every room has Wifi. If you do that scan you will get a lot of results with the same SSIDs but with different acces points, and thus different signal level.

EDIT: According to Walt's comment you can also have multiple results despite having only one access point if your modem is dual-band.

DuKes0mE
  • 1,101
  • 19
  • 30
  • what could possibly makes the difference between those APs? something like BSSID or channel or something else? and how do i get them? – randms26 Apr 20 '13 at 12:29
  • Yeah, BSSID makes the difference if I remember correctly. For getting those check: [ScanResult API](http://developer.android.com/reference/android/net/wifi/ScanResult.html). Or in other words: String bssid = scanresult.BSSID like you did with "ssid" – DuKes0mE Apr 20 '13 at 13:00
  • Okay it has different bssid, your answer is accepted, thanks :). Just one more confusion , should I consider these as 1 same AP or is it different? (all AP with same ssid but different bssid) – randms26 Apr 21 '13 at 02:37
  • 3
    If your app is only scanning available wifi networks you can consider all Access Points as the same network. You can do something like a HashMap. For each scan you could insert the SSID into the key field and its signal level into the value field of this hashmap. If the SSID is in the HashMap already, compare the signal level and replace it with the better value. So with this hashmap you can get results with only one SSID and the best signal level among all those multiple Access Points – DuKes0mE Apr 21 '13 at 09:26
  • 1
    This also appears to be the case when a wireless access point is dual band. I see it on my home router and there is a single access point. – Walt Oct 07 '13 at 03:32
3

use below code to to remove duplicate ssids with highest signal strength

public void onReceive(Context c, Intent intent) {
    ArrayList<ScanResult> mItems = new ArrayList<>();
    List<ScanResult> results = wifiManager.getScanResults();
    wifiListAdapter = new WifiListAdapter(ConnectToInternetActivity.this, mItems);
    lv.setAdapter(wifiListAdapter);
    int size = results.size();
    HashMap<String, Integer> signalStrength = new HashMap<String, Integer>();
    try {
        for (int i = 0; i < size; i++) {
            ScanResult result = results.get(i);
            if (!result.SSID.isEmpty()) {
                String key = result.SSID + " "
                        + result.capabilities;
                if (!signalStrength.containsKey(key)) {
                    signalStrength.put(key, i);
                    mItems.add(result);
                    wifiListAdapter.notifyDataSetChanged();
                } else {
                    int position = signalStrength.get(key);
                    ScanResult updateItem = mItems.get(position);
                    if (calculateSignalStength(wifiManager, updateItem.level) >
                            calculateSignalStength(wifiManager, result.level)) {
                        mItems.set(position, updateItem);
                        wifiListAdapter.notifyDataSetChanged();
                    }
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Artificioo
  • 704
  • 1
  • 9
  • 19
vikoo
  • 2,451
  • 20
  • 27
  • 1
    algorithm seems to be a bit flawed at `ScanResult updateItem = mItems.get(position);` since there is nothing that guarantees that an item is at that position unless you do `mItems.add(result, position);` – John61590 Jul 12 '18 at 22:28
0

This is my simple Solution please and it is work for me

private void scanWifiListNew() {
    wifiManager.startScan();
    List<ScanResult>  wifiList = wifiManager.getScanResults();
    mWiFiList = new ArrayList<>();

    for(ScanResult result: wifiList){
       checkItemExists(mWiFiList, result);
    }

    setAdapter(mWiFiList);
}


private void printList(List<ScanResult> list){
    for(ScanResult result: list){
        int level = WifiManager.calculateSignalLevel(result.level, 100);
        System.out.println(result.SSID + " Level is " + level + " out of 100");
    }
}

private void checkItemExists(List<ScanResult> newWiFiList, ScanResult resultNew){
    int indexToRemove = -1;

    if(newWiFiList.size() > 0) {
        for (int i = 0; i < newWiFiList.size(); i++) {
            ScanResult resultCurrent = newWiFiList.get(i);

            if (resultCurrent.SSID.equals(resultNew.SSID)) {
                int levelCurrent = WifiManager.calculateSignalLevel(resultCurrent.level, 100);
                int levelNew = WifiManager.calculateSignalLevel(resultNew.level, 100);
                if (levelNew > levelCurrent) {
                    indexToRemove = i;
                    break;
                }else indexToRemove = -2;
            }
        }
        if(indexToRemove > -1){
            newWiFiList.remove(indexToRemove);
            newWiFiList.add(indexToRemove,resultNew);
        }else  if(indexToRemove == -1)newWiFiList.add(resultNew);
    } else newWiFiList.add(resultNew);
}

private void setAdapter(List<ScanResult> list) {
    listAdapter = new WifiListAdapter(getActivity().getApplicationContext(), list);
    wifiListView.setAdapter(listAdapter);

}
Dulanga
  • 921
  • 11
  • 23