Friday, March 13, 2015

Programmatically joining WiFi network from Xamarin Android

I'm currently working on a project where I need to programmatically join a WiFi network from a Xamarin Forms Android app.  It turns out to be pretty simple.  I take the extra step of checking to see if the network is in the list first, though I'm not sure it's necessary.  It also takes care of a few more things:
  • SetWifiEnabled makes sure that the radio is turned on
  • UpdateNetwork checks to see if the network for the given SSID has changed.  Could happen if you used the same SSID on a new router maybe
  • Disconnect takes you off of whatever network you might be associated with
  • EnableNetwork with true makes sure that the given SSID is active and that no others are
  • CreateWifiLock prevents the OS from disabling the radio or putting it in low-power mode
  • SaveConfiguration makes the network changes permanent in the list of networks
It was so much easier than I expected!
public bool JoinWifi(string ssid, string key)
{
try
{
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.Ssid = String.Format("\"{0}\"", ssid);
wifiConfig.PreSharedKey = String.Format("\"{0}\"", key);
WifiManager wifiManager = (WifiManager)GetSystemService(Context.WifiService);
wifiManager.SetWifiEnabled(true);
 
// Get or add network to known list
int netId;
var network = wifiManager.ConfiguredNetworks.FirstOrDefault(cn=>cn.Ssid == ssid);
if( network != null ) netId = network.NetworkId;
else
{
netId = wifiManager.AddNetwork(wifiConfig);
wifiManager.SaveConfiguration();
}
 
// Make sure network hasn't changed
wifiManager.UpdateNetwork(wifiConfig);
var currConn = wifiManager.ConnectionInfo;
if( currConn != null && currConn.NetworkId != netId )
{
wifiManager.Disconnect();
wifiManager.EnableNetwork(netId, true);
wifiManager.Reconnect();
}
 
// Make sure system doesn't save power by disabling WiFi
wifiManager.CreateWifiLock(Android.Net.WifiMode.Full, "myLockId");
return true; 
}
catch( Exception x) {
return false;
}
}