Search code examples
c#androidxamarin.androidwifiwireless

Xamarin - Reliable way to see device is connected to Wifi network (Android)


I am building a mobile application on Android and the user can decide not to send data if not connected to Wifi in a configurable settings, as follows:

enter image description here

I am looking a reliable way to check this and have come up with this solution:

public class AndroidDeviceNetwork : IDeviceNetwork
{
    private const string UNKNOWNSSID = "<unknown ssid>";

    /// <summary>
    /// Detects if the device has wifi turned on (does not take into account if the
    /// device is connected to a wifi network, only the fact its switched on).
    /// </summary>
    /// <returns>True if switched on only. False if not switched on.</returns>
    public bool IsWifiEnabled()
    {
        var wifiManager = Application.Context.GetSystemService(Context.WifiService) 
            as WifiManager;

        if (wifiManager != null)
        {
            // Check state is enabled.
            return wifiManager.IsWifiEnabled; 
        }

        return false;
    }

    /// <summary>
    /// Checks wifi is switched on AND that its connected (using NetworkId and SSID to 
    /// identify connected).
    /// </summary>
    /// <returns>True if switched on and connected to a wifi network.  False if not switch on 
    /// OR if switched on but not connected.</returns>
    public bool IsWifiConnected()
    {
        var wifiManager = Application.Context.GetSystemService(Context.WifiService) 
            as WifiManager;

        if (wifiManager != null)
        {
            // Check state is enabled.
            return wifiManager.IsWifiEnabled &&
                // Check for network id equal to -1
                (wifiManager.ConnectionInfo.NetworkId != -1
                // Check for SSID having default value of "<unknown SSID>"
                && wifiManager.ConnectionInfo.SSID != UNKNOWNSSID);
        }
        return false;
    }
}

Can anyone verify if this is a good way to check if a user is connected to a wireless network (IsWifiConnected() method)? Or if there is a more reliable way?

Thanks in advance!


Solution

  • Just for reference - this is the class I came up with to manager this (Android only solution):

    public class AndroidDeviceNetwork : IDeviceNetwork
    {
        private const string UNKNOWNSSID = "<unknown ssid>";
    
        public NetworkState GetNetworkState()
        {
            var connMgr = Application.Context.GetSystemService(Context.ConnectivityService)
                as ConnectivityManager;
    
            if (connMgr == null)
                return NetworkState.NoNetwork;
    
            var activeNetwork = connMgr.ActiveNetworkInfo;
    
            if (activeNetwork == null || !activeNetwork.IsConnectedOrConnecting)
                return NetworkState.NoNetwork;
    
            if (activeNetwork.Type == ConnectivityType.Wifi)
                return  NetworkState.WiFi;
    
            if (activeNetwork.Type == ConnectivityType.Mobile)
                return NetworkState.Mobile;
    
            return NetworkState.NoNetwork;
        }
    
        /// <summary>
        /// Detects if the device has wifi turned on (does not take into account if the
        /// device is connected to a wifi network, only the fact its switched on).
        /// </summary>
        /// <returns>True if switched on only. False if not switched on.</returns>
        public bool IsWifiEnabled()
        {
            var wifiManager = Application.Context.GetSystemService(Context.WifiService)
                as WifiManager;
    
            // Check state is enabled.
            if (wifiManager != null)
                return wifiManager.IsWifiEnabled;
    
            return false;
        }
    
        /// <summary>
        /// Detects if the device has MobileData turned on 
        /// </summary>
        /// <returns>True if switched on only. False if not switched on.</returns>
        public bool IsMobileDataEnabled()
        {
            var connectivityManager = (ConnectivityManager)Application.Context.GetSystemService(Context.ConnectivityService);
            var networkInfo = connectivityManager?.ActiveNetworkInfo;
            return networkInfo?.Type == ConnectivityType.Mobile;
        }
    
        /// <summary>
        /// Checks wifi is switched on AND that its connected (using NetworkId and SSID to 
        /// identify connected).
        /// </summary>
        /// <returns>True if switched on and connected to a wifi network.  False if not switch on 
        /// OR if switched on but not connected.</returns>
        public bool IsWifiConnected()
        {
            var wifiManager = Application.Context.GetSystemService(Context.WifiService) as WifiManager;
    
            if (wifiManager != null)
            {
                // Check state is enabled.
                return wifiManager.IsWifiEnabled &&
                    // Check for network id equal to -1
                    (wifiManager.ConnectionInfo.NetworkId != -1
                    // Check for SSID having default value of "<unknown SSID>"
                    && wifiManager.ConnectionInfo.SSID != UNKNOWNSSID);
            }
    
            return false;
        }
    }
    

    I implemented the IDeviceNetwork interface, so that this can be injected into a common library that works across platform. The simple interface looks like this:

    public interface IDeviceNetwork
    {
        bool IsWifiEnabled();
        bool IsWifiConnected();
        NetworkState GetNetworkState();
    }
    

    Hope that's useful to someone else!