Search code examples
androidios.netxamarintimeout

.net or Xamarin Internet availability check when the WIFI network has no internet connection


i know its a big discussion how to check if there is a internet connection available for the device.

I tried Ping, WebClient and HTTPClient. I also use Xamarin Essentials and the Connectivity Plugin.

All this things are working, just make a request to google or the server of your choice and you will get back the answer or not. You can also set a timeout for 2 seconds and so on.

But now i came to the situation where i'm connected to the WIFI BUT the WIFI itself has no active internet connection.

So all the things i wrote about was not working anymore. The problem is that the timeout will be ignored somehow. Maybe a bug in .net? I don't know.

Now i found one last thing:

try
        {
            var request = (HttpWebRequest)WebRequest.Create("https://www.google.com");
            request.KeepAlive = false;
            request.Timeout = 2000;

            using (var response = (HttpWebResponse)await request.GetResponseAsync())
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    //Connection to internet available
                    return true;
                }
                else
                {
                    //Connection to internet not available
                    return false;
                }
            }
        }
        catch (WebException webEx)
        {
            if (webEx.Status == WebExceptionStatus.Timeout)
            {
                return false;
            }
        }
        catch (Exception e)
        {
            return false;
        }

This was the only solution where i got the WebException when the 2 seconds timeout was reached. In all other solutions i stuck more than 1 minute till the timeout was reached. Also when i set it to 500ms or something.

Did anybody know the reason why the given timeout is not reached for example with other methodes about?


Solution

  • Solution:

    You can use DependencyServiceto implement it .Refer the following code.

    in Forms ,create an interface

    using System;
    namespace app1
    {
      public interface INetworkAvailable
      {
    
        bool IsNetworkAvailable();
      }
    }
    

    in iOS project

    using System;
    using Xamarin.Forms;
    using Foundation;
    
    [assembly: Dependency(typeof(IsNetworkAvailableImplement))]
    namespace xxx.iOS
    {
      public class IsNetworkAvailableImplement:INetworkAvailable
      {
        public IsNetworkAvailableImplement()
        {
        }
    
        bool INetworkAvailable.IsNetworkAvailable()
        {
            NSString urlString = new NSString("http://captive.apple.com");
    
            NSUrl url = new NSUrl(urlString);
    
            NSUrlRequest request = new NSUrlRequest(url, NSUrlRequestCachePolicy.ReloadIgnoringCacheData, 3);
    
            NSData data = NSUrlConnection.SendSynchronousRequest(request, out NSUrlResponse response, out NSError error);
    
            NSString result = NSString.FromData(data,NSStringEncoding.UTF8);
    
            if(result.Contains(new NSString("Success")))
            {
                return true;
            }
    
            else
            {
                return false;
            }
    
        }
      }
    }
    

    Don't forget to allow HTTP access .add the following code in info.plist

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict> 
    

    in Android project

    using System;
    using Java.Lang;
    using Xamarin.Forms;
    
    [assembly: Dependency(typeof(IsNetworkAvailableImplement))]
    namespace xxx.Droid
    {
      public class IsNetworkAvailableImplement:INetworkAvailable
      {
        public IsNetworkAvailableImplement()
        {
        }
    
        public bool IsNetworkAvailable()
        {
            Runtime runtime = Runtime.GetRuntime();
    
            Process process = runtime.Exec("ping -c 3 www.google.com");
    
            int result = process.WaitFor();
    
            if(result==0)
            {
                return true;
            }
    
            else
            {
                return false;
            }
        }
      }
    }
    

    Now you can call it in forms ,just like

    bool isAvailable= DependencyService.Get<INetworkAvailable>().IsNetworkAvailable();
    
    if(isAvailable)
    {
      Console.WriteLine("network is available");
    }
    
    else
    {
      Console.WriteLine("network is unavailable");
    }