Подтвердить что ты не робот

Android 5.0 Lollipop и 4.4 KitKat игнорирует мою сеть WiFi, enableNetwork() бесполезен

Мое приложение подключается непосредственно к аппаратным устройствам, которые действуют как точка доступа (без доступа к Интернету).

Я не могу подключиться, потому что Android 5.0 автоматически переключается на действующее подключение к Интернету, поэтому, если у меня есть подключение к данным (3G, 4G,...) или предварительно настроенная сеть, я не могу подключиться к своему устройству, потому что это игнорирует WiFi.

Итак, как я могу заставить Android использовать сеть, которую я активировал программно?

Я просто использую:

wifiManager.enableNetwork(id, true))

где id - это сеть моего устройства, к которому я хочу подключиться. Параметр true бесполезен.

Предлагаемое решение, использующее ConnectivityManager.requestNetwork(), не имеет эффекта.

4b9b3361

Ответ 1

Я нашел обходное решение, чтобы включить доступную сеть на Lollipop:

WifiConfiguration включить сеть в Lollipop

Теперь это мой код после вызова wifiManager.enableNetwork(id, true):

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    List<WifiConfiguration> networks = wm.getConfiguredNetworks();
    Iterator<WifiConfiguration> iterator = networks.iterator();
    while (iterator.hasNext()) {
        WifiConfiguration wifiConfig = iterator.next();
        if (wifiConfig.SSID.replace("\"", "").equals(wc.SSID.replace("\"", "")))
            wm.enableNetwork(wifiConfig.networkId, true);
        else
            wm.disableNetwork(wifiConfig.networkId);
    }
    wm.reconnect();
}

Возможно, секрет - это вызов reconnect(), я не знаю в это время.

UPDATE К сожалению, это обходное решение работает только в том случае, если действительное соединение WiFi активно перед выполнением кода. Не работает, если вы подключаетесь только через 3G.

ОБНОВЛЕНИЕ 19 января 2015 г.

Этот код действительно работает для меня на Android 5/6.0.x:

//bind to current thread
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder request = new NetworkRequest.Builder();
    request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
    connManager.registerNetworkCallback(request.build(), new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(Network network) {
            ConnectivityManager.setProcessDefaultNetwork(network);
            //...
        }
    });
}

Ответ 2

Вы можете попробовать использовать новый Lollipop API ConnectivityManager.requestNetwork(), предположительно вот так:

ConnectivityManager cm = (ConnectivityManager) Context.getSystemService(Context.CONNECTIVITY_SERVICE);
cm.requestNetwork(new NetworkRequest.Builder()
                  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                  .setNetworkSpecifier("XX:XX:XX:XX:XX:XX")
                  .build(),
                  new ConnectivityManager.NetworkCallback() {
                      void onAvailable(Network network) {

                      }
                  });

где XX:XX:XX:XX:XX:XX - ваш SSID WiFi. Я не уверен в этом формате, и если он вообще используется, я не нашел ссылок на setNetworkSpecifier в источниках Android, кроме класса NetworkCapabilities.

Ответ 3

Просто нужно правильно форматировать SSID. Вот пример кода:

    WifiManager mWifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
    WifiConfiguration tmpConfig = new WifiConfiguration();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        tmpConfig.SSID = String.format("\"%s\"", sSSID);
        tmpConfig.BSSID = sBSSID;
    } else {
        tmpConfig.SSID = "\"" + sSSID + "\"";
        tmpConfig.BSSID = "\"" + sBSSID + "\"";
    }

    tmpConfig.priority = 1;
    if (iSecurityType.equals("WEP")) {
        tmpConfig.wepKeys[0] = sPassword;
        tmpConfig.wepTxKeyIndex = 0;
    } else if (iSecurityType.equals("WPA2") ||   iSecurityType.equals("WPA")) {
            tmpConfig.preSharedKey = "\"" + sPassword+ "\"";
        } else {
            tmpConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }

    tmpConfig.status = WifiConfiguration.Status.ENABLED;
    int netId = mWifiManager.addNetwork(tmpConfig);

    mWifiManager.updateNetwork(tmpConfig);
    boolean result = mWifiManager.enableNetwork(netId, true);
    mWifiManager.updateNetwork(tmpConfig);
    mWifiManager.saveConfiguration();