319

I want to design an app which shows a list of Wi-Fi networks available and connect to whichever network is selected by the user.

I have implemented the part showing the scan results. Now I want to connect to a particular network selected by the user from the list of scan results.

How do I do this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vikram Gupta
  • 6,496
  • 5
  • 34
  • 47
  • Related: ["How to programatically create and read WEP/EAP WiFi configurations in Android?"](http://stackoverflow.com/questions/4374862/how-to-programatically-create-and-read-wep-eap-wifi-configurations-in-android/4374934#4374934) – Brad Larson Nov 06 '14 at 16:09
  • This worked for me WPA2 and WEP: https://stackoverflow.com/a/29575563/7337517 – Kundan Jul 22 '19 at 09:12

11 Answers11

468

You need to create WifiConfiguration instance like this:

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes

Then, for WEP network you need to do this:

conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 

For WPA network you need to add passphrase like this:

conf.preSharedKey = "\""+ networkPass +"\"";

For Open network you need to do this:

conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

Then, you need to add it to Android wifi manager settings:

WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
wifiManager.addNetwork(conf);

And finally, you might need to enable it, so Android connects to it:

List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
    if(i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
         wifiManager.disconnect();
         wifiManager.enableNetwork(i.networkId, true);
         wifiManager.reconnect();               

         break;
    }           
 }

UPD: In case of WEP, if your password is in hex, you do not need to surround it with quotes.

Jon
  • 9,156
  • 9
  • 56
  • 73
kenota
  • 5,640
  • 1
  • 15
  • 11
  • 5
    that works well! thank you :) but one more thing i would like to ask. Dont you need to set the allowedPairwiseCipher, allowedAuthALgorithms and allowedProtocols? And how to decide which particular attribute to set; like you set WEP40 for GroupCipher for WEP networks? – Vikram Gupta Jan 11 '12 at 11:59
  • 2
    One way you can figure out which attributes to set is by connecting manually to network and then using readConfig functions from Mike code example. – kenota Jan 11 '12 at 13:01
  • i'm not able to connect to WEP networks. It shows: obtaining IP address form bsc2... and then it fails to connect. What can be the problem?? i can connect to open and WPA secured networks but not with WEP – Vikram Gupta Jan 12 '12 at 09:35
  • Are you able to connect to this network manually through android settings using same password? – kenota Jan 12 '12 at 10:05
  • 8
    I forgot to mention one thing. In case of WEP, if your password is in hex, you do not need to surround it by quotes. – kenota Jan 12 '12 at 10:18
  • yes i'm able to connect to it through android settings. i'll try without quotes – Vikram Gupta Jan 12 '12 at 10:20
  • Can anyone please tell, if the above code will also work in case of WEP/EAP enabled wifi ? – Me-an-Droid Jan 16 '13 at 06:04
  • @Me-an-Droid it will work for WEP, for EAP networks use approach described here: http://stackoverflow.com/questions/4374862/how-to-programatically-create-and-read-wep-eap-wifi-configurations-in-android – kenota Jan 16 '13 at 11:06
  • Does it work also for wifi networks tethered from another android device? I cant' let it work! – phcaze Mar 06 '13 at 06:44
  • @phcaze it should not matter. Check your settings especially on android phone which provides wifi network, may be it has some kind of "White list" or device limit. Also check if you can connect manually using usual Settings on Android. – kenota Mar 06 '13 at 10:08
  • @kenota, it was an SSID name problem, it works! For the solution go to: http://stackoverflow.com/questions/15225232/programmatically-connect-to-an-android-device-in-portable-hotspot – phcaze Mar 07 '13 at 07:18
  • 8
    Thanks for the nice solution, could you elaborate on how to check if the connection was successful or not. For example the user might enter the wrong password and should be notified about it. – Pascal Klein Mar 29 '13 at 00:50
  • I follow this procedure and no errors occur from the specified method calls, but the NetworkInfo object returned by ConnectivityManager.getWifiNetworkInfo() says isConnected() is false. Am I leaving out a step? – user604713 Nov 18 '13 at 22:00
  • @user604713 it takes some time for connection to happen and obviously, you should be in range of hotspot. – kenota Nov 19 '13 at 12:25
  • I followed the instructions but its not working I am currently debugging on Motorola Razr i running android 4.1.2 no errors are thrown, and I am in range of the hotspot – B. TIger May 13 '14 at 13:25
  • 3
    how about if the desired Wifi Hotspot doesn't use any Password at all.... Should we use the .preSharedKey = null; or should we set .preSharedKey = ""; Which one is correct? @kenota – gumuruh Jul 19 '14 at 06:08
  • 1
    @gumuruh for open network you skip section configuring WEP keys and preSharedKey (do not write anything), but only specify that network is open by conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); – kenota Jul 20 '14 at 10:25
  • alright.... let me try first that concept. @kenota, i just wondering what is the effect if i write everything (the code) just like this page: http://stackoverflow.com/questions/24837337/which-one-is-the-best-practice-to-connect-wifi-under-android – gumuruh Jul 21 '14 at 07:34
  • and one more thing... if i use open network, which contain no password at all... is the code of conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); should be erased as well? @kenota – gumuruh Jul 26 '14 at 05:50
  • @gumuruh for open network your code would be probably look like this: https://gist.github.com/kenota/0f088ad9df78cbd3d1fd – kenota Aug 12 '14 at 10:36
  • @kenota incredible answer and it just make the job, but if you illustrate why setting the configuration like that in each line of code, it will be a Marvelous answer, greetings – Muhammed Refaat Sep 29 '14 at 08:03
  • Where do we set the security type in configuration – Utsav Gupta Oct 18 '14 at 05:15
  • Is there are some specific handling for WPA2 ? – unresolved_external Jan 29 '15 at 16:15
  • @unresolved_external no, just follow generic "WPA" path. – kenota Jan 29 '15 at 16:48
  • I have tried using your code sample to connect to the WiFi (see http://stackoverflow.com/questions/29117522/cant-connect-to-wifi-network). But when i try to call the method to connect, I keep on getting android.system.ErrNoException: recvfrom failed: ETIMEDOUT (Connection timed out). error...Any ideas how to fix this? – user869375 Mar 18 '15 at 08:53
  • I have used this code to connect but i am unable to do it. My problem is : http://stackoverflow.com/questions/29232706/connecting-to-mobile-hotspot-network-programmatically-from-android-device] – Kushal Mar 24 '15 at 12:58
  • @kenota: It always crashes at `for (WifiConfiguration i = list ){` line, saying, in the LogCat, that: _java.lang.IllegalStateException: Could not execute method of the activity_, any idea what might be the problem ?! – McLan Apr 14 '15 at 16:14
  • @kenota how do I know if this password it's valid or not? or even who can I know if it's connecting or not? – Skizo-ozᴉʞS ツ Jul 07 '15 at 12:11
  • @kenota first of all thanks for your solution , it's works for me in lower version and what about higher version like lolipop . In there i had problem can you please post some thing for that – Mohan Jul 21 '15 at 06:14
  • 10
    It doesnt work for me: it does reconnecting directly to the previous remembered wifi instead of connecting to the new one. – Virthuss Jan 15 '16 at 04:46
  • I am trying to implement this code but the first time I connect to a network gives me a wrong IP address of the router(0.0.0.0). However if I run this code for a second time it works absolutely fine. Any idea whis this happens? – Sourav Kanta Mar 11 '16 at 16:07
  • @kenota hello it's possible to get WIFI Password using coding in android ? – Hardik Parmar May 11 '16 at 12:34
  • On Android M (6.0) and up, the SSID string goes WITHOUT quotes, otherwise it doesn't seem to work. – Fernando Gallego Jun 16 '16 at 08:55
  • can you suggest me to how to connect to EAP of SIM type? – Prashanth Debbadwar Aug 01 '16 at 11:43
  • Can you please update the list for IEEE8021X and WPA_EAP ? – android developer Nov 13 '16 at 13:58
  • @PascalKlein To check if connecting succeeded or not, you need to make a broadcast receiver to receive SUPPLICANT_CONNECTION_CHANGE_ACTION – York Yang Jul 03 '17 at 23:38
  • i want to add wifi which is not already added my device so this code is not working. what is problem? – Dhara Patel Oct 07 '17 at 06:52
  • Works perfect.. is there any way to disable mobile data at the same time – Vishnu M Menon Oct 23 '17 at 07:33
  • I facing an issue in this. When I restart device save passwords with these codes removed automatically. Is there any solution for these??? @kenota – Upendra Shah Nov 30 '17 at 07:56
  • @kenota How can I checked the wifi password is correct or not. Bcz in this case working for me after reboot the device only. otherwise If I checked public static boolean isConnectionNetwork() { final ConnectivityManager connectivityManager = ((ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE)); assert connectivityManager != null; return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected(); } Then it's always false until reboot the device – AngelJanniee Dec 20 '17 at 08:32
  • I used your guide and create a method in order to connect to wifi but it doesn't work for me! I really appreciate if you can help. https://stackoverflow.com/questions/47968837/cant-connect-to-selected-wifi – Ehsan Dec 25 '17 at 18:44
  • heads up!! ``wifiManager.getConfiguredNetworks() is null`` if wifi is not open (scanning nearby wifi) – bh_earth0 May 07 '18 at 08:15
  • @Virthuss how did you solve this issue? (That your WIFI connected to the previously remembered one and not the requested one) – Keselme Jul 29 '18 at 16:31
  • @Keselme, Mine is also connecting to the last known connection.. Did you find a solution? – Luciano Sep 11 '18 at 15:11
  • @Virthuss @Keselme @Luciano the same was happening to me because the new network was already saved. Calls to `addNetwork()` will return `-1` (failure) if that's the case (see https://stackoverflow.com/a/53018931/595881). If the new network is already saved, you can just connect straight to it, you don't need to add it. – Flávio Faria Jan 22 '19 at 18:37
  • 1
    does this still work with recent versions of android? – Waterfr Villa May 22 '19 at 06:20
  • It would be great if you had also explained how to check the return status for example connected or failure! – Muhammad Babar Apr 14 '20 at 10:38
  • In Android 10, this is not working for me: if I have two networks available and ask the app to switch, the phone disconnects, but then randomly reconnects either to the one I give it, or the previous one. – Luis A. Florit Apr 19 '20 at 19:55
  • @FlávioFaria: The problem persists even without the `addNetwork()`. The method randomly reconnects either to the one I give it, or the previous one. – Luis A. Florit Apr 19 '20 at 20:05
  • This solution doesn't work anymore for android API level 29 and above. Take a look on this post: https://stackoverflow.com/questions/56905956/is-it-possible-to-add-a-network-configuration-on-android-q – aguiarroney Jul 07 '22 at 18:46
147

The earlier answer works, but the solution can actually be simpler. Looping through the configured networks list is not required as you get the network id when you add the network through the WifiManager.

So the complete, simplified solution would look something like this:

WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
wifiConfig.preSharedKey = String.format("\"%s\"", key);

WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
//remember id
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
Community
  • 1
  • 1
sean loyola
  • 1,739
  • 1
  • 11
  • 11
  • I am trying to do this but its not working I've executed it on a async task to allow it time to process and nothing how should i do this? – B. TIger May 14 '14 at 18:38
  • 2
    if the password is not used. Should we put .preSharedKey = null; or should we just put empty string, @seanloyola ? – gumuruh Jul 19 '14 at 06:14
  • why making `disconnect` before connecting ? – Muhammed Refaat Oct 15 '14 at 13:18
  • 2
    @MuhammedRefaat you disconnect incase you are already connected to another network. – sean loyola Oct 22 '14 at 21:11
  • 1
    @gumuruh you dont have to include the presharedkey object at all if there is no key required. – sean loyola Oct 22 '14 at 21:12
  • 7
    according to the javadoc of enableNetwork, if you use boolean disableOthers true, then you dont have to disconnect or connect, it will do both for you – NikkyD Mar 17 '15 at 16:20
  • 16
    Should probably mention that the `CHANGE_WIFI_STATE` permission is needed. – ThomasW May 27 '15 at 06:34
  • 1
    Thanks it helped to me, but how I know if this returns true or false, I mean if it's connected or password it's accepted or not? Is there any method or something? – Skizo-ozᴉʞS ツ Jul 07 '15 at 12:09
  • @NikkyD, I tried not including disconnect() and reconnect() and was unsucessful, did it work for you? – MikeF Jun 07 '16 at 16:49
  • Fails on Google Pixel phones – gregm Feb 09 '17 at 17:18
  • It works well on Lollipop but fails on Marshmallow. Does it have anything to do with this : https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-network ? – Greelings Apr 10 '17 at 17:25
  • I've tried this method on watch with Android 8.1 and I didn't have to do disconnect() and reconnect(). enableNetwork() was enough to get it working, so potentially this answer could be further simplified. – LLL Oct 15 '18 at 11:36
  • @LLL In my test, if you already have a connection and want to connect to the new SSID, you will need to `disconnect`, `enableNetwork`, `reconnect`. Otherwise, just like what you experienced. – Dino Tw Mar 28 '19 at 00:14
  • can we get any kind of event if the wifi is unable to connect a defined SSID and password @seanloyola? – Kuls Jul 02 '19 at 05:49
  • 1
    Please note -> wifiManager.addNetwork(wifiConfig) will fail and return -1 if the network ssid is already present in the configured networks and also it will fail if the password length is less than 8 chars. – rd7773 Aug 20 '20 at 07:49
  • I'm on API 30 and working with existing code and it looks just like this answer! But, almost every line shows as deprecated! And all calls to wifiManager methods return false. Is this old info? – steve Aug 04 '23 at 17:48
33

Before connecting WIFI network you need to check security type of the WIFI network ScanResult class has a capabilities. This field gives you type of network

Refer: https://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities

There are three types of WIFI networks.

First, instantiate a WifiConfiguration object and fill in the network’s SSID (note that it has to be enclosed in double quotes), set the initial state to disabled, and specify the network’s priority (numbers around 40 seem to work well).

WifiConfiguration wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid).concat("\"");
wfc.status = WifiConfiguration.Status.DISABLED;
wfc.priority = 40;

Now for the more complicated part: we need to fill several members of WifiConfiguration to specify the network’s security mode. For open networks.

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.clear();
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

For networks using WEP; note that the WEP key is also enclosed in double quotes.

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

if (isHexString(password)) wfc.wepKeys[0] = password;
else wfc.wepKeys[0] = "\"".concat(password).concat("\"");
wfc.wepTxKeyIndex = 0;

For networks using WPA and WPA2, we can set the same values for either.

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

wfc.preSharedKey = "\"".concat(password).concat("\"");

Finally, we can add the network to the WifiManager’s known list

WifiManager wfMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int networkId = wfMgr.addNetwork(wfc);
if (networkId != -1) {
 // success, can call wfMgr.enableNetwork(networkId, true) to connect
} 
Jørgen R
  • 10,568
  • 7
  • 42
  • 59
  • a note on priority, on my phone numbers around 4000 worked. probable best to make that part a little more dynamic (iterate existing configs etc) – Sam Jun 01 '15 at 14:24
  • How could I get network security type from SSID for wifi ScanResult – shantanu Dec 14 '15 at 19:26
  • @shantanu check following for detail. http://stackoverflow.com/questions/6866153/android-determine-security-type-of-wifi-networks-in-range-without-connecting-t – Kalpesh Gohel Jan 20 '16 at 12:32
  • On samsung devices, the passphrase is hashed string. And The code doesn't work. Do you check that? – Nguyen Minh Binh May 31 '16 at 23:56
  • can you provide a sample to connect EAP of sim type wifi? – Prashanth Debbadwar Aug 01 '16 at 12:54
  • 1
    Password length also needs to be greater than 8 otherwise wfMgr.addNetwork(wfc) will return -1. Also, SSID should not be in the pre-configured networks list, else -1 will be returned by addNetwork() – rd7773 Aug 20 '20 at 07:53
20

Credit to @raji-ramamoorthi & @kenota

The solution which worked for me is combination of above contributors in this thread.

To get ScanResult here is the process.

WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (wifi.isWifiEnabled() == false) {
            Toast.makeText(getApplicationContext(), "wifi is disabled..making it enabled", Toast.LENGTH_LONG).show();
            wifi.setWifiEnabled(true);
        }

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context c, Intent intent) {
                 wifi.getScanResults();
            }
        };

Notice to unregister it on onPause & onStop live this unregisterReceiver(broadcastReceiver);

public void connectWiFi(ScanResult scanResult) {
        try {

            Log.v("rht", "Item clicked, SSID " + scanResult.SSID + " Security : " + scanResult.capabilities);

            String networkSSID = scanResult.SSID;
            String networkPass = "12345678";

            WifiConfiguration conf = new WifiConfiguration();
            conf.SSID = "\"" + networkSSID + "\"";   // Please note the quotes. String should contain ssid in quotes
            conf.status = WifiConfiguration.Status.ENABLED;
            conf.priority = 40;

            if (scanResult.capabilities.toUpperCase().contains("WEP")) {
                Log.v("rht", "Configuring WEP");    
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
                conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
                conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
                conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

                if (networkPass.matches("^[0-9a-fA-F]+$")) {
                    conf.wepKeys[0] = networkPass;
                } else {
                    conf.wepKeys[0] = "\"".concat(networkPass).concat("\"");
                }

                conf.wepTxKeyIndex = 0;

            } else if (scanResult.capabilities.toUpperCase().contains("WPA")) {
                Log.v("rht", "Configuring WPA");

                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 + "\"";

            } else {
                Log.v("rht", "Configuring OPEN network");
                conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
                conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
                conf.allowedAuthAlgorithms.clear();
                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);
            }

            WifiManager wifiManager = (WifiManager) WiFiApplicationCore.getAppContext().getSystemService(Context.WIFI_SERVICE);
            int networkId = wifiManager.addNetwork(conf);

            Log.v("rht", "Add result " + networkId);

            List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
            for (WifiConfiguration i : list) {
                if (i.SSID != null && i.SSID.equals("\"" + networkSSID + "\"")) {
                    Log.v("rht", "WifiConfiguration SSID " + i.SSID);

                    boolean isDisconnected = wifiManager.disconnect();
                    Log.v("rht", "isDisconnected : " + isDisconnected);

                    boolean isEnabled = wifiManager.enableNetwork(i.networkId, true);
                    Log.v("rht", "isEnabled : " + isEnabled);

                    boolean isReconnected = wifiManager.reconnect();
                    Log.v("rht", "isReconnected : " + isReconnected);

                    break;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
Rohit Mandiwal
  • 10,258
  • 5
  • 70
  • 83
12

In API level 29, WifiManager.enableNetwork() method is deprecated. As per Android API documentation(check here):

  1. See WifiNetworkSpecifier.Builder#build() for new mechanism to trigger connection to a Wi-Fi network.
  2. See addNetworkSuggestions(java.util.List), removeNetworkSuggestions(java.util.List) for new API to add Wi-Fi networks for consideration when auto-connecting to wifi. Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always return false.

From API level 29, to connect to WiFi network, you will need to use WifiNetworkSpecifier. You can find example code at https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder.html#build()

VIjay J
  • 736
  • 7
  • 14
  • Is it possible to connect to a WEP network with the new WifiNetWorkSpecifier.Builder? I cannot find a method to add a WEP passphrase to the builder. – Dieter27 Apr 07 '20 at 21:07
  • Number 1 doesnt seem to work is there any callback to it ? – Faizan Mir Apr 15 '20 at 09:44
  • 2
    #1 doesn’t work as well, the device shows a prompt to connect to the network, but there’s no internet connection. As per the documentation: “These specifiers can only be used to request a local wifi network (i.e no internet capability).” — and I couldn’t get the #2 to do anything, just shows a wifi icon with “?”. – KBog Oct 16 '20 at 20:11
  • Any way to use this method, switch networks and `not prompt a user`? – Roy Hinkley Jan 28 '22 at 21:47
6

If your device knows the Wifi configs (already stored), we can bypass rocket science. Just loop through the configs an check if the SSID is matching. If so, connect and return.

Set permissions:

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

Connect:

    try {
    String ssid = null;
    if (wifi == Wifi.PCAN_WIRELESS_GATEWAY) {
        ssid = AesPrefs.get(AesConst.PCAN_WIRELESS_SSID,
                context.getString(R.string.pcan_wireless_ssid_default));
    } else if (wifi == Wifi.KJ_WIFI) {
        ssid = context.getString(R.string.remote_wifi_ssid_default);
    }

    WifiManager wifiManager = (WifiManager) context.getApplicationContext()
            .getSystemService(Context.WIFI_SERVICE);

    List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();

    for (WifiConfiguration wifiConfiguration : wifiConfigurations) {
        if (wifiConfiguration.SSID.equals("\"" + ssid + "\"")) {
            wifiManager.enableNetwork(wifiConfiguration.networkId, true);
            Log.i(TAG, "connectToWifi: will enable " + wifiConfiguration.SSID);
            wifiManager.reconnect();
            return null; // return! (sometimes logcat showed me network-entries twice,
            // which may will end in bugs)
        }
    }
} catch (NullPointerException | IllegalStateException e) {
    Log.e(TAG, "connectToWifi: Missing network configuration.");
}
return null;
Martin Pfeffer
  • 12,471
  • 9
  • 59
  • 68
6

I broke my head to understand why your answers for WPA/WPA2 don't work...after hours of tries I found what you are missing:

conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

is REQUIRED for WPA networks!!!!

Now, it works :)

Taras Okunev
  • 410
  • 6
  • 9
4

This is an activity you can subclass to force the connecting to a specific wifi: https://github.com/zoltanersek/android-wifi-activity/blob/master/app/src/main/java/com/zoltanersek/androidwifiactivity/WifiActivity.java

You will need to subclass this activity and implement its methods:

public class SampleActivity extends WifiBaseActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  }

  @Override
  protected int getSecondsTimeout() {
      return 10;
  }

  @Override
  protected String getWifiSSID() {
      return "WifiNetwork";
  }

  @Override
  protected String getWifiPass() {
      return "123456";
  }
}
Zoltan Ersek
  • 755
  • 9
  • 28
4

I also tried to connect to the network. None of the solutions proposed above works for hugerock t70. Function wifiManager.disconnect(); doesn't disconnect from current network. Аnd therefore cannot reconnect to the specified network. I have modified the above code. For me the code bolow works perfectly:

String networkSSID = "test";
String networkPass = "pass";

WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + networkSSID + "\"";   
conf.wepKeys[0] = "\"" + networkPass + "\""; 
conf.wepTxKeyIndex = 0;
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); 
conf.preSharedKey = "\""+ networkPass +"\"";

WifiManager wifiManager =         
(WifiManager)context.getSystemService(Context.WIFI_SERVICE);    

int networkId = wifiManager.addNetwork(conf);
wifi_inf = wifiManager.getConnectionInfo();

/////important!!!
wifiManager.disableNetwork(wifi_inf.getNetworkId());
/////////////////

wifiManager.enableNetwork(networkId, true);
Abe
  • 4,500
  • 2
  • 11
  • 25
user1277317
  • 127
  • 11
  • I get an error in Android 10: `UID nnnnn does not have permission to update configuration xxxx. MD_START_CONNECT but no requests and connected, but app does not have sufficient permissions, bailing.` – Luis A. Florit Apr 19 '20 at 20:01
  • thx! worked for me with a Alcatel 5041C with Android 8.1. You can see it disconnecting from the current wifi before connecting to new one – save_jeff Dec 05 '20 at 13:12
3

Get list Wifi, connect to Wifi (Android <=9 and Android >=10)

[assembly: Xamarin.Forms.Dependency(typeof(WifiService))]
namespace configurator.Droid.Services
{
   public class WifiService : IWifiService
 {
    private bool _requested;
    private bool _statusConnect;

    private NetworkCallback _callback;
    private Context _context = null;
    private Version _version;
    private WifiManager _wifiManager = null;
    private ConnectivityManager _connectivityManager;
    private WifiConfiguration _config;
    private int _temp = -1;

    public WifiService()
    {
        this._context = Android.App.Application.Context;
        _version = DeviceInfo.Version;
        _wifiManager = _context.GetSystemService(Context.WifiService) as WifiManager;
    }

    [Obsolete]
    public async Task<bool> ConnectToWifiAsync(string ssid, string password, Action<bool> animation = null)
    {
        if (!_wifiManager.IsWifiEnabled)
        {
            if (_version.Major >= 9)
            {
                bool result =  await Device.InvokeOnMainThreadAsync(async () => await Application.Current.MainPage.DisplayAlert("", "The program requires accesss to Wi-Fi. Turn on Wi-fi?", "Ok", "Cancel")) ;

                if (!result)
                {
                    return false;
                }

                Intent intent;

                if (_version.Major == 9)
                {
                    intent = new Intent(Android.Provider.Settings.ActionWifiSettings);
                }
                else
                {
                    intent = new Intent(Android.Provider.Settings.Panel.ActionInternetConnectivity);
                }

                intent.AddFlags(ActivityFlags.NewTask);
                Android.App.Application.Context.StartActivity(intent);
            }
            else
            {
                _wifiManager.SetWifiEnabled(true);
            }
        }
        else
        {

            if (_version.Major <= 9 && _version.Major >= 8)
            {
                await Device.InvokeOnMainThreadAsync(async () => await Geolocation.GetLastKnownLocationAsync());
                JoinToWifiLessAndroidQAsync(ssid, password, animation);
            }
            else if(_version.Major < 8)
            {
                JoinToWifiLessAndroidQAsync(ssid, password, animation);
            }
            else
            {
                await Device.InvokeOnMainThreadAsync(async () => await Geolocation.GetLastKnownLocationAsync());
                await JoinToWifiMoreAndroidPie(ssid, password);
            }
        }
        
        return await Task.FromResult(_statusConnect);
    }

    [Obsolete]
    public async Task<IEnumerable<string>> GetAvailableNetworksAsync()
    {
        
        IEnumerable<string> availableNetworks = null;

        // Get a handle to the Wifi
        if (!_wifiManager.IsWifiEnabled)
            _wifiManager.SetWifiEnabled(true);
        var wifiReceiver = new WifiReceiver(_wifiManager);

        await Task.Run(() =>
        {
            // Start a scan and register the Broadcast receiver to get the list of Wifi Networks
            _context.RegisterReceiver(wifiReceiver, new IntentFilter(WifiManager.ScanResultsAvailableAction));
            availableNetworks = wifiReceiver.Scan();
        });

        return availableNetworks;
    }

    private class NetworkCallback : ConnectivityManager.NetworkCallback
    {
        private ConnectivityManager _connectivityManager;

        public NetworkCallback(ConnectivityManager connectivityManager)
        {
            _connectivityManager = connectivityManager;
        }
        public Action<Network> NetworkAvailable { get; set; }
        public Action NetworkUnavailable { get; set; }

        public override void OnAvailable(Network network)
        {
            _connectivityManager.BindProcessToNetwork(network);
            base.OnAvailable(network);
            NetworkAvailable?.Invoke(network);
        }

        public override void OnUnavailable()
        {
            base.OnUnavailable();
            NetworkUnavailable?.Invoke();
        }
    }

    [BroadcastReceiver(Enabled = true, Exported = false)]
    class WifiReceiver : BroadcastReceiver
    {
        private WifiManager _wifi;
        private List<string> _wifiNetworks;
        private AutoResetEvent _receiverARE;
        private Timer _tmr;
        private const int TIMEOUT_MILLIS = 20000; // 20 seconds timeout

        public WifiReceiver()
        {

        }

        public WifiReceiver(WifiManager wifi)
        {
            this._wifi = wifi;
            _wifiNetworks = new List<string>();
            _receiverARE = new AutoResetEvent(false);
        }

        [Obsolete]
        public IEnumerable<string> Scan()
        {
            _tmr = new Timer(Timeout, null, TIMEOUT_MILLIS, System.Threading.Timeout.Infinite);
            _wifi.StartScan();
            _receiverARE.WaitOne();
            return _wifiNetworks;
        }

        public override void OnReceive(Context context, Intent intent)
        {
            IList<ScanResult> scanwifinetworks = _wifi.ScanResults;
            foreach (ScanResult wifinetwork in scanwifinetworks)
            {
                _wifiNetworks.Add(wifinetwork.Ssid);
            }

            _receiverARE.Set();
        }

        private void Timeout(object sender)
        {
            // NOTE release scan, which we are using now, or we throw an error?
            _receiverARE.Set();
        }
    }

    [Obsolete]
    private void JoinToWifiLessAndroidQAsync(string ssid, string password, Action<bool> animation)
    {
        animation?.Invoke(true);

        _config = new WifiConfiguration
        {
            Ssid = "\"" + ssid + "\"",
            PreSharedKey = "\"" + password + "\""
        };

        try
        {
            _temp = _wifiManager.AddNetwork(_config);
            _wifiManager.Disconnect();
            var result = _wifiManager.EnableNetwork(_temp, true);
            _wifiManager.Reconnect();

            int i = 0;

            do
            {
                Thread.Sleep(2000);
                //wait connection
                i++;
                if (i == 7)
                    break;

            } while (GetCurrentConnectName() != ssid);

            Thread.Sleep(6000);

            if (i == 7)
            {
                throw new Exception("Connect to PC failed. Long time connect(14000ms)");
            }
            else
            {
                _statusConnect = true;
            }                
        }
        catch (Exception ex)
        {
            Helpers.Logger.Error($"{nameof(WifiService)}||JoinToWifiLessAndroidQ||{ex.Message}");
            _statusConnect = false;
        }
    }

    [Obsolete]
    private async Task<bool> JoinToWifiMoreAndroidPie(string ssid, string password)
    {
        var specifier = new WifiNetworkSpecifier.Builder()
                       .SetSsid(ssid)
                       .SetWpa2Passphrase(password)
                       .Build();
                      
        var request = new NetworkRequest.Builder()
                       .AddTransportType(TransportType.Wifi) 
                       .RemoveCapability(NetCapability.Internet) 
                       .SetNetworkSpecifier(specifier) 
                       .Build();

        _connectivityManager = _context.GetSystemService(Context.ConnectivityService) as ConnectivityManager;

        if (_requested)
        {
            _connectivityManager.UnregisterNetworkCallback(_callback);
        }

        bool confirmConnect = false;

        _callback = new NetworkCallback(_connectivityManager)
        {
            NetworkAvailable = network =>
            {
                // we are connected!
                _statusConnect = true;
                confirmConnect = true;
            },
            NetworkUnavailable = () =>
            {
                _statusConnect = false;
                confirmConnect = true;
            }
        };

        _connectivityManager.RequestNetwork(request, _callback);
        _requested = true;

        do
        {
            //wait callback
            await Task.Delay(TimeSpan.FromSeconds(5));
            Helpers.Logger.Info($"{nameof(WifiService)}||JoinToWifiMoreAndroidPie||Waiting callback....");

        } while (!confirmConnect);

        return await Task.FromResult(true);
    }

    public string GetCurrentConnectName()
    {
        WifiInfo wifiInfo = _wifiManager.ConnectionInfo;
        if (wifiInfo.SupplicantState == SupplicantState.Completed)
        {
            char[] chars = {'\"'};
            var masChar = wifiInfo.SSID.Trim(chars);
            return masChar;
        }
        else
        {
            return null;
        }
    }

    [Obsolete]
    public async Task ReconnectToWifi()
    {
        if (_version.Major > 9)
        {
            _connectivityManager.UnregisterNetworkCallback(_callback);
            await Task.Delay(10000);
            var network = _connectivityManager.ActiveNetwork;

            if(network == null)
            {
                var dataNetwork = await ManagerSecureStorage.GetConnectedNetworkInfo();
                await JoinToWifiMoreAndroidPie(dataNetwork["NetName"], dataNetwork["Password"]);
            }
            else
            {
                _connectivityManager.BindProcessToNetwork(network);
            }
        }
        else
        {
            if(_temp == -1)
            {
                var temp = _wifiManager.ConfiguredNetworks;
                _temp = temp.Last().NetworkId;
            }
            
            _wifiManager.RemoveNetwork(_temp);
            _wifiManager.Reconnect();
            await Task.Delay(10000);
        }
    }
  }
}
1

Try this method. It's very easy:

public static boolean setSsidAndPassword(Context context, String ssid, String ssidPassword) {
    try {
        WifiManager wifiManager = (WifiManager) context.getSystemService(context.WIFI_SERVICE);
        Method getConfigMethod = wifiManager.getClass().getMethod("getWifiApConfiguration");
        WifiConfiguration wifiConfig = (WifiConfiguration) getConfigMethod.invoke(wifiManager);

        wifiConfig.SSID = ssid;
        wifiConfig.preSharedKey = ssidPassword;

        Method setConfigMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
        setConfigMethod.invoke(wifiManager, wifiConfig);

        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hiren Vaghela
  • 61
  • 1
  • 1
  • 6