Connecting to WiFi network automatically in Android 5 and 6
Asked Answered
E

1

2

Been struggling with connecting to WiFi network in Android 5 and 6 for a while and other similar questions don't seem to work for me. I could get the same code working in Android 4.4.2

Adding the code snippet below.

        String networkSSID = getSsid();
        String networkPass = getNetworkPass();

        WifiConfiguration conf = new WifiConfiguration();
        conf.SSID = "\"" + networkSSID + "\"";
        conf.status = WifiConfiguration.Status.ENABLED;
        conf.priority = 40;

        conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

        conf.preSharedKey = "\""+ networkPass +"\"";
        int value = mWifiManager.addNetwork(conf);
        Log.i(TAG_CHECK, "Connecting to : " + value);
        boolean enabled = mWifiManager.enableNetwork(value, true);
        Log.i(TAG_CHECK, "enabled to : " + enabled);
        mWifiManager.reconnect();

And here is what I noticed.

mWifiManager.addNetwork(conf)

returns some (+) integer with Android 5(phone) and Android 6(tab).

But both don't connect unless I open the wifi settings (I don't have to do anything and just landing there connects) or I manually turn off and turn on Wifi from the top bar to automatically connect.

The listeners to detect connection to the network are in tact for both the versions to precisely know when the connection get established - confirming the above behaviour. Have attached a pic of the permissions granted below.

Any pointers as to what I am missing?

EDIT: Upon digging into WifiManager class, looks like the Access Point remains in WIFI_AP_STATE_DISABLED state. I should also highlight that everything worked as expected while trying on a different Android M phone.

EDIT2

I have the following observations.

1. The issue so far is specific to 1 android 6.0.1 Samsung tablet and 1 android 5.0.2 Micromax phone. It works just fine on 3 other android 6.0.1 phones, 1 android N phone and Android 4.4.2 phone. 
2. The access point ends up in wifi_ap_disabled state in the problematic cases consistently. Both addNetwork and enableNetwork calls are affirmative.
3. These access points are not that of a router wifi but that of other phones that broadcast. The problematic phones can programatically connect to wifi hotspots (setup manually and not in the programatic way as I would like to) without any issue.
4. Mobile data enabled/disabled state or wifi state with a different connected network doesn't change the dynamics for both working and problematic phones. 

This makes me think that it is a combination of phones/tabs (and not OS) and the access point broadcast configuration. Do you think I should be playing around with some config parameters?



Edit 3 - Important Update

So the wifimanager is obtained like below

WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

I instantiate mWifiManager in a service (inside onCreate method) and use that later to scan and connect with inputs from front-end activity. While it doesn't work in the way as described earlier, using the same snippet seems to work when the enableNetwork call is done right in the onCreate method - working just as expected. It also works fine when called from front-end activity but only when I don't instantiate mWifiManager in the service.

Though I would expect only one reference to a system service - WifiManager i.e, I think the subsequent usage of that reference (or a different reference to WifiManager) gets a lower priority (or gets deprioritized  by the previous reference)  and hence doesn't get completely executed leaving the access point in disabled state and requiring manual intervention to help complete the execution by WifiManager and other wifi system services.

Also, I notice the same in Android 5.0.2 phone, the asynchronous enableNetwork does get executed, but it takes some time to execute it.

My questions
1. It is no more a question about the correctness of the code. Services in general have lesser priority compared to front-end threads So, is there is way I could prioritise the enableNetwork call so that it gets immediately executed?
2. What happens in case of multiple references to WifiManager? 

App permissions

Eggert answered 18/1, 2017 at 6:3 Comment(4)
Are you already connected to mobile data or any other WiFI SSID when trying to connect to a particular SSID? Can you try adding a NetworkCallback using ConnectivityManager and see if you get onNetworkAvailable() for the SSID that you are trying to connect to. I would also suggest registering for NETWORK_STATE_CHANGED_ACTION and WIFI_STATE_CHANGED_ACTION broadcasts and see different states of network and wifi during the attempt to connect.Millhon
I have added the listeners to detect state change and I do not get any callbacks whatsoever. Added some edits with my observations.Eggert
Is there any particular reason to get the instance of WifiManager from a service? Are you sharing the instance across your Service and Activities or is it only the Service that's interacting with WifiManager? Also all of these methods should give you state change callbacks for different states. I don't think it's a problem with multiple references but about synchronization of events. enableNetwork() itself attempts to connect to the provided networkId so you should not be needing to execute it immediately (you wouldn't need a reconnect() to attempt connection)Millhon
There is only instance in the service that interacts with WifiManager. I indeed get affirmative values with addNetwork and enableNetwork calls. But the end state of the access point is WIFI_AP_DISABLED. Making the same calls from onCreate or for that matter from activity seems to make it work fine.Eggert
E
0

I believe if you add a disconnect() it will do what you want. I've added a check here because addNetwork() can fail to add your network. For Android 6.0+, you can't add a network if it exists already but if this fails you can try getting the network id then connecting. (For instance, it will be there if added (and saved) if you re-install) I also do not add quotes to SSID in Lollipop (ver 21)+.

int value = mWifiManager.addNetwork(conf);
// need to check the result if successful
if (value == -1) {
    return; // network not added successfully
}
Log.i(TAG_CHECK, "Connecting to : " + value);
mWifiManager.disconnect();  // add a disconnect
boolean enabled = mWifiManager.enableNetwork(value, true);
Log.i(TAG_CHECK, "enabled to : " + enabled);
mWifiManager.reconnect();
Echinate answered 26/1, 2017 at 2:8 Comment(1)
I am indeed getting the right network id(which is already added anyway) but enableNetwork doesn't seem to work. But the current network (different from the target one) seems to disconnect in any case whether I disconnect explicitly or not. I am having trouble debugging the WifiManager in Android SDK. I see other functions executing other the enableNetwork. My suspicion is that it results in WIFI_AP_STATE_DISABLED state for some reason for the target network. And upon going to wifi settings screen, it connects.Eggert

© 2022 - 2024 — McMap. All rights reserved.