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

大憨熊 提交于 2019-12-14 01:53:13

问题


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?


回答1:


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");
} 



回答2:


Xamarin Essentials in best solution as it offers more options, this is a sample how to use it

            if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.Internet)
            {
                IsBusy = true;
                var products = new ObservableRangeCollection<Product>();
                var apiProducts = await _homeService.GetProducts();
                IsBusy = false;
                return apiProducts.ToModel<Product>();
            }
            else
            {
                await DialogService.ShowAlertAsync("No Internet Connection", "Internet", "Ok");
                IsBusy = false;
                return new ObservableRangeCollection<Product>();                   
            }

look at this: https://github.com/xamarin/Essentials



来源:https://stackoverflow.com/questions/54197727/net-or-xamarin-internet-availability-check-when-the-wifi-network-has-no-interne

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!