How do I connect to a specific Wi-Fi network in Android programmatically?
AndroidAndroid WifiWifimanagerAndroid Problem Overview
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?
Android Solutions
Solution 1 - Android
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.
Solution 2 - Android
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();
Solution 3 - Android
> 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
}
Solution 4 - Android
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();
}
}
Solution 5 - Android
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()
Solution 6 - Android
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;
Solution 7 - Android
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 :)
Solution 8 - Android
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";
}
}
Solution 9 - Android
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);
Solution 10 - Android
Get list Wifi, connect to Wifi (Android <=9 and Android >=10)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Net;
using Android.Net.Wifi;
using Xamarin.Essentials;
[assembly: Xamarin.Forms.Dependency(typeof(Wifi))]
namespace configurator.Droid.Services
{
public class Wifi : IWifi
{
private NetworkCallback _callback;
private bool _requested;
private Context _context = null;
private WifiManager _wifiManager = null;
private string _statusText;
public Wifi()
{
this._context = Android.App.Application.Context;
}
[Obsolete]
public void ConnectToWifi(string ssid, string password)
{
if (!_wifiManager.IsWifiEnabled)
_wifiManager.SetWifiEnabled(true);
Version version = Xamarin.Essentials.DeviceInfo.Version;
if (version.Major <= 9 && version.Minor < 9)
{
var config = new WifiConfiguration();
config.Ssid = "\"" + ssid + "\"";
config.PreSharedKey = "\"" + password + "\"";
var temp = _wifiManager.AddNetwork(config);
_wifiManager.Disconnect();
_wifiManager.EnableNetwork(temp, true);
_wifiManager.Reconnect();
}
else
{
var specifier = new WifiNetworkSpecifier.Builder()
.SetSsid(ssid)
.SetWpa2Passphrase(password)
.Build();
var request = new NetworkRequest.Builder()
.AddTransportType(TransportType.Wifi) // we want WiFi
.RemoveCapability(NetCapability.Internet) // Internet not required
.SetNetworkSpecifier(specifier) // we want _our_ network
.Build();
var connectivityManager = _context.GetSystemService(Context.ConnectivityService) as ConnectivityManager;
if (_requested)
{
connectivityManager.UnregisterNetworkCallback(_callback);
}
_callback = new NetworkCallback
{
NetworkAvailable = network =>
{
// we are connected!
_statusText = $"Request network available";
},
NetworkUnavailable = () =>
{
_statusText = $"Request network unavailable";
}
};
connectivityManager.RequestNetwork(request, _callback);
_requested = true;
}
}
[Obsolete]
public async Task<IEnumerable<string>> GetAvailableNetworksAsync()
{
var location = await Geolocation.GetLastKnownLocationAsync();
IEnumerable<string> availableNetworks = null;
// Get a handle to the Wifi
_wifiManager =
`(WifiManager)_context.GetSystemService(Context.WifiService);`
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
{
public Action<Network> NetworkAvailable { get; set; }
public Action NetworkUnavailable { get; set; }
public override void OnAvailable(Network 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();
}
}
}
}
Solution 11 - Android
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;
}
}