Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.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?

like image 536
Stefan Habacher Avatar asked Oct 17 '22 08:10

Stefan Habacher


1 Answers

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");
} 
like image 122
Lucas Zhang Avatar answered Oct 21 '22 05:10

Lucas Zhang