当 WIFI 网络没有互联网连接时,.net 或 Xamarin 互联网可用性检查
.net or Xamarin Internet availability check when the WIFI network has no internet connection
我知道这是一个很大的讨论如何检查设备是否有可用的互联网连接。
我尝试了 Ping、WebClient 和 HTTPClient。
我还使用 Xamarin Essentials 和连接插件。
所有这些都在工作,只需向 google 或您选择的服务器发出请求,您就会得到答案。
也可以设置超时2秒等。
但现在我遇到了这样的情况:我已连接到 WIFI,但 WIFI 本身没有活动的互联网连接。
所以我写的所有东西都不再起作用了。问题是超时会以某种方式被忽略。也许是 .net 中的错误?我不知道。
现在我发现了最后一件事:
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;
}
这是我在达到 2 秒超时时收到 WebException 的唯一解决方案。
在所有其他解决方案中,我停留了超过 1 分钟,直到达到超时。另外,当我将它设置为 500 毫秒或其他内容时。
有没有人知道为什么没有达到给定超时的原因,例如使用其他方法?
解法:
可以使用DependencyService
来实现,参考下面的代码。
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;
}
}
}
}
不要忘记允许 HTTP 访问。在 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;
}
}
}
}
现在可以在表单中调用它了,就像
bool isAvailable= DependencyService.Get<INetworkAvailable>().IsNetworkAvailable();
if(isAvailable)
{
Console.WriteLine("network is available");
}
else
{
Console.WriteLine("network is unavailable");
}
已编辑: Xamarin Essentials 是最好的解决方案,因为它提供了更多选项,这是如何使用它的示例
在您的项目中设置 Xamarin Essential NuGet 之后
你的代码我们是这样的
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.Internet)
{
//your Code if there is an internet
}
else
{
//your Code if there isn't an internet
}
我知道这是一个很大的讨论如何检查设备是否有可用的互联网连接。
我尝试了 Ping、WebClient 和 HTTPClient。 我还使用 Xamarin Essentials 和连接插件。
所有这些都在工作,只需向 google 或您选择的服务器发出请求,您就会得到答案。 也可以设置超时2秒等。
但现在我遇到了这样的情况:我已连接到 WIFI,但 WIFI 本身没有活动的互联网连接。
所以我写的所有东西都不再起作用了。问题是超时会以某种方式被忽略。也许是 .net 中的错误?我不知道。
现在我发现了最后一件事:
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;
}
这是我在达到 2 秒超时时收到 WebException 的唯一解决方案。 在所有其他解决方案中,我停留了超过 1 分钟,直到达到超时。另外,当我将它设置为 500 毫秒或其他内容时。
有没有人知道为什么没有达到给定超时的原因,例如使用其他方法?
解法:
可以使用DependencyService
来实现,参考下面的代码。
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;
}
}
}
}
不要忘记允许 HTTP 访问。在 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;
}
}
}
}
现在可以在表单中调用它了,就像
bool isAvailable= DependencyService.Get<INetworkAvailable>().IsNetworkAvailable();
if(isAvailable)
{
Console.WriteLine("network is available");
}
else
{
Console.WriteLine("network is unavailable");
}
已编辑: Xamarin Essentials 是最好的解决方案,因为它提供了更多选项,这是如何使用它的示例
在您的项目中设置 Xamarin Essential NuGet 之后
你的代码我们是这样的
if (Xamarin.Essentials.Connectivity.NetworkAccess == Xamarin.Essentials.NetworkAccess.Internet) { //your Code if there is an internet } else { //your Code if there isn't an internet }