0

I have a problem connecting programmatically my device to a specific SSID. In particular I noticed that: If I connect manually the device to the SSID (Swipe down with my little finger, timid tap on the SSID), then my code to connect to that SSID work. If the SSID is a new SSID that my device doesn't never connected before, then the code not works, but if connect manually work. This is so strange, I can't figure out how to solve it.

I'm using Xamarin.Forms and Xamarin.Android, with Android 9.0 API 28 - Pie.

There is the code i use to (attempt to) connect:

public int ConnectToSSID(string SSID, string password)
    {
        var wifiConfiguration = new WifiConfiguration();
        wifiConfiguration.Ssid = '"' + SSID + '"';
        if (password.Length > 0)
        {
            wifiConfiguration.PreSharedKey = '"' + password + '"';
        }
        
        if (wifiManager == null)
        {
            wifiManager = (WifiManager)context.GetSystemService(Context.WifiService);
        }

        wifiManager.AddNetwork(wifiConfiguration);

        IList<WifiConfiguration> list = wifiManager.ConfiguredNetworks;
        foreach (WifiConfiguration conf in list)
        {
            if (conf.Ssid.Equals('"' + SSID +'"'))
            {
                wifiManager.Disconnect();
                wifiManager.EnableNetwork(conf.NetworkId, true);
                wifiManager.Reconnect();
                return 1;
            }
        }
        return 0;
    }

2 Answers2

0

To connect to a specific SSID programmatically, try using the following code.

string ssid = "\"" + _ssid + "\"";
string password = "\"" + _password + "\"";

var wifiConfig = new WifiConfiguration
{
    Ssid = ssid,
    PreSharedKey = password
};

var wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(WifiService);
var addNetwork = wifiManager.AddNetwork(wifiConfig);

var list = wifiManager.ConfiguredNetworks;
foreach (var wifiConfiguration in list)
{
    if (wifiConfiguration.Ssid != null && WifiConfiguration.Ssid.Equals("\"" + _ssid + "\""))
    {
        wifiManager.Disconnect();
        wifiManager.EnableNetwork(WifiConfiguration.NetworkId, true);
        wifiManager.Reconnect();
        break;
    }
}
Jarvan Zhang
  • 968
  • 3
  • 11
  • 84
  • No, it doesn't work, unless I do the first connection by Settings > Wi-Fi > mySSID. Then, after the first association with the network, it works. – Cosimo Davide Viggiano Oct 14 '20 at 13:01
  • Make sure you've added the required permissions, such as: ` `. I tested the code on my side, it works fine. – Jarvan Zhang Oct 14 '20 at 13:11
  • Yes, I added the required permission. However I noticed a thing just a moment ago, after the call wifiManager.addNetwork(wifiConfig); I wanted to check personally the list ConfiguredNetwork with a logger and the network was not added. Why? – Cosimo Davide Viggiano Oct 14 '20 at 13:30
  • Did you initialize the before? `if (wifiManager == null)` Check if the wifiManager instance is correct. Try using the following code to get the WifiManager. `var wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(WifiService);` – Jarvan Zhang Oct 14 '20 at 13:39
  • I changed the code with your suggestion and added a Log, now the code is: 'wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService); Debug.WriteLine(wifiManager.ToString()); var addNetwork = wifiManager.AddNetwork(wifiConfiguration); Debug.WriteLine("ID == " + addNetwork);'. And the result was '[0:] android.net.wifi.WifiManager@18f0dca8 [0:] ID == -1'. So the AddNetwork method failed, I think. However thanks a lot for your time. – Cosimo Davide Viggiano Oct 14 '20 at 13:53
  • I already readed that link before I post the question. I really tried a lot this morning. I checked in the foreach (Wificonfiguration conf in list) if(conf.ssid.Equals("\"" + SSID + "\"")). But it doesn't find anything (unless I manually connect the SSID in the phone settings). My opinion is that simply AddNetwork(wifiConfiguration); doesn't add the configuration. – Cosimo Davide Viggiano Oct 14 '20 at 14:22
  • Did you test the project on Android 10? What the version of **Targer Framework** of the project. The `addNetwork` method is deprecated in API level 29.Try using `addNetworkSuggestions` method instead in Android 10. Check the doc:https://developer.android.com/reference/android/net/wifi/WifiManager#addNetwork(android.net.wifi.WifiConfiguration) Realted link:https://stackoverflow.com/a/58947697/11083277 – Jarvan Zhang Oct 15 '20 at 07:28
  • The target version of the project is Android 9.0 API Level 28, and the minimum version is Android 5.0 API Level 21. The phone I use to test is a HUAWEI MYA-L11 with Android 6.0 (API Level 23) installed. I really don't understand why the WifiManager class doesn't add the configuration, maybe I miss something. – Cosimo Davide Viggiano Oct 15 '20 at 08:00
  • Ok I got it! The WifiManager refuse the WifiConfiguration if AllowedKeyManagement property is not setted. You need to add the properly KeyManagementType: wifiConf.AllowedKeyManagement.Set((int) KeyManagementType.None); In the docs the say to use WifiConfiguration.KeyManagement.None, but this is deprecated and removed from the APIs. It works perfectly now. – Cosimo Davide Viggiano Oct 15 '20 at 13:40
  • Congrats! Please post your solution and accept it as the answer. It will be beneficial for other community members who have similar questions. – Jarvan Zhang Oct 15 '20 at 14:14
0

Ok I figured out what was the real problem: the WifiManager class fails to add a new WifiConfiguration. Then the configuration was never picked from the ConfiguredNetworks list and never connect to it.

To solve this problem is necessary specify the security of the WifiConfiguration We want to connect to.

Be aware to the changes done to the APIs because the docs suggest to use:

WifiConfiguration conf = new WifiConfiguration();
conf.AllowedKeyManagement.Set(WifiConfiguration.[KEY_MANAGEMENT_CONST]);

But this doesn't work anymore, instead you have to use:

WifiConfiguration conf = new WifiConfiguration();
conf.AllowedKeyManagement.Set((int)KeyManagementType.[KEY_MANAGEMENT_CONST]);

Now my method to connect is:

public int ConnectToSSID(string SSID, string password)
    { 
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        wifiConfiguration.Ssid =  '"' + SSID + '"';
        wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
        
        wifiManager = (WifiManager)context.GetSystemService(Context.WifiService);

        var addNet = wifiManager.AddNetwork(wifiConfiguration);
        if (addNet == -1)
        {
            addNet = wifiManager.UpdateNetwork(wifiConfiguration);
        }
        if (addNet == -1)
        {
            return 0; //Error!
        }
        var list = wifiManager.ConfiguredNetworks;
        foreach (WifiConfiguration conf in list)
        {
            if (conf.Ssid.Equals('"' + SSID + '"'))
            {
                wifiManager.Disconnect();
                wifiManager.EnableNetwork(conf.NetworkId, true);
                wifiManager.Reconnect();
                return 1;
            }
        }
        return 0;
    }