25

My app connect directly to a hardware device that act as an access point (with no access to internet).

I can't connect because Android 5.0 automaticcaly switch to a valid internet connection, so if I have data connection (3G, 4G, ...) or a pre-configured network I can't connect to my device because it ignores the WiFi.

So how can I force Android to use the network I activated programatically?

I'm simply using:

wifiManager.enableNetwork(id, true))

where id is the network of my device I want to connect to. The true parameter is useless.

The suggested solution that use ConnectivityManager.requestNetwork() has no effect.

Seraphim's
  • 11,736
  • 17
  • 80
  • 126
  • 3
    I strongly suggest you file a bug on b.android.com to get the official take on this. IMO as per the documentation of `wifiManager.enableNetwork(id, true)`, thinks should continue working as they were before. If they don't then it is a bug. Also, what devices have you tried? – curioustechizen Dec 04 '14 at 05:30
  • @curioustechizen I'm on a nexus 5 with lollipop – Seraphim's Dec 04 '14 at 11:24
  • @curioustechizen As you say, enableNetwork() should continue working, I found a solution. – Seraphim's Dec 19 '14 at 16:57

3 Answers3

8

You can try to use new Lollipop API ConnectivityManager.requestNetwork(), supposedly like this:

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) {

                      }
                  });

where XX:XX:XX:XX:XX:XX is your WiFi SSID. I'm not sure about it's format, and if it's used at all, I did not find any references to setNetworkSpecifier inside Android sources, except for the NetworkCapabilities class.

Seraphim's
  • 11,736
  • 17
  • 80
  • 126
pelya
  • 4,031
  • 2
  • 22
  • 20
7

I found a workaround to enable the desidered network on Lollipop:

WifiConfiguration enable network in Lollipop

Now this is my code after calling 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();
}

maybe the secret is the call to reconnect(), I don't know at this time.

UPDATE Unfortunately, this workaround only works if a valid WiFi connection is active before executing the code. Does not works if you're connect by 3G only.

UPDATE 19 Jan 2015

This code actually works for me on 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);
            //...
        }
    });
}
Seraphim's
  • 11,736
  • 17
  • 80
  • 126
1

Just need to correctly format the SSID. Here is a sample code:

    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();