Android Wifi в роуминге через точку доступа с тем же SSID

Я видел, что система Android плохо себя ведет с роумингом Wi-Fi. У нас есть централизованная сеть Wi-Fi со многими точками доступа с SSID. Телефоны Android не будут перемещаться без проблем. Android-телефон пытается оставаться подключенным к точке доступа до тех пор, пока сигнал не достигнет нуля, даже если есть другие точки доступа (с тем же SSID) с хорошим сигналом! Когда сигнал равен нулю, наконец, он выполняет ассоциацию с другой точкой доступа (с хорошим сигналом). Но при таком поведении телефон теряет все TCP соединения!

Например:

  1. телефон подключен в WiFi к AP1
  2. телефон перемещается в здании и теперь слышит два сигнала от AP1 и от AP2.
  3. Когда сигнал от AP2 сильнее, чем сигнал от AP1, я хочу, чтобы телефон выполнял повторное связывание (не связывание) с AP2.

Идея такова:

  • Выполните WifiManager.startScan()
  • Получить результаты WifiManager.getScanResults()
  • Найдите лучшую точку доступа в результатах
  • Выполните повторное сопоставление с лучшей точкой доступа.

Повторяйте каждые 30 секунд.

Я говорю о реассоциации, потому что не хочу, чтобы телефон терял TCP-соединения.

Есть способ сделать это?

Спасибо, Сальво


person Salvo Parisi    schedule 21.06.2016    source источник


Ответы (2)


Вы не можете сделать это, как вы описываете. Клиент не может самостоятельно определить состояние TCP-соединения. Ваша сеть также должна перемещать канал связи с одной точки доступа на другую. Это можно сделать с помощью правильных сетевых контроллеров.

Кроме того, вам следует взглянуть на IEEE 802.11k — https://en.wikipedia.org/wiki/IEEE_802.11k-2008

person Jim    schedule 15.05.2017

Добавьте ниже разрешения;

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

Зарегистрируйтесь для ниже намерения;

private WifiBroadcastReceiver wifiBroadcastReceiver = new WifiBroadcastReceiver();

Затем в рутине;

registerReceiver(wifiBroadcastReceiver, new IntentFilter("android.net.wifi.SCAN_RESULTS"));

Используйте приведенный ниже класс, чтобы изменить повторную ассоциацию;

public class WifiBroadcastReceiver extends BroadcastReceiver {

    private WiFiManager manager = null;//set the value in constructor
    private WifiConfiguration connectedConfiguration = null;//set the value in constructor
    private int connectedNetId;

    private void updateConnectedConfiguration(String ssid) {
        configs = manager.getConfiguredNetworks();
        int nid = 0;
        for (WifiConfiguration cnf : configs) {
            if (cnf.SSID.substring(1, cnf.SSID.length() - 1).equals(ssid)) {
                connectedConfiguration = cnf;
                connectedNetId = nid;
            }
            nid++;
        }
    }


    public void onReceive(Context c, Intent intent) {
        List<ScanResult> results = manager.getScanResults();
        WifiInfo info = manager.getConnectionInfo();
        ScanResult stronger = null;
        for (ScanResult scanResult : results) {
            try {
                if (scanResult.SSID.equals(info.getSSID())) {
                    if (stronger == null) {
                        if (WifiManager.compareSignalLevel(info.getRssi() + 5, scanResult.level) < 0) {
                            stronger = scanResult;
                        }
                    } else if (WifiManager.compareSignalLevel(stronger.level, scanResult.level) < 0) {
                        stronger = scanResult;
                    }
                }
            } catch (Exception e) {
            }
        }
        if (stronger != null && !stronger.BSSID.equals(info.getBSSID())) {
            updateConnectedConfiguration(info.getSSID());
            if (connectedConfiguration != null) {
                connectedConfiguration.BSSID = stronger.BSSID;
                manager.updateNetwork(connectedConfiguration);
                manager.saveConfiguration();
                manager.enableNetwork(connectedNetId, true);
                manager.reassociate();
                info = manager.getConnectionInfo();
                //showNotification("\nConnecting " + stronger.SSID, stronger.BSSID + " " + stronger.level + "dBm");
            }
        }
    }
}
person Samantha    schedule 23.07.2019
comment
Куда добавить этот фрагмент кода? Какой файл в каком каталоге? К чему добавить рутину? Вы тестировали этот код? - person Jonathan Ben-Avraham; 08.10.2019
comment
Фрагмент кода можно добавить в ваше приложение. Ваше приложение при запуске выполняет повторную ассоциацию. Вы можете найти сторонние приложения в магазине приложений с такой реализацией. Код был протестирован. Спасибо. - person Samantha; 08.10.2019