Android - 检查数据连接是否正常工作

Android - checking if data connection is actually working

我目前有一个特殊的用例,我很困惑如何解决。

我们一直在检查与 ConnectivityService 的互联网连接,其中包含 ConnectivityType.Wifi / ConnectivityType.Mobile 如果 已连接/正在连接 ,则带有 属性。这一切都很好,直到你 运行 进入以下情况:

我以为我会简单地检查如下:

private static bool CanReachServer()
        {
            var uri = new Uri(Platform.ApiServerUrl); // replace with https://www.google.com if you like
            try
            {
                using (HttpClient httpClient = new HttpClient())
                {
                    httpClient.Timeout = TimeSpan.FromMilliseconds(5000);
                    HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
                    var task = httpClient.SendAsync(httpRequestMessage);
                    task.Wait();
                    if (task.Result.IsSuccessStatusCode)
                        return true;
                    else
                        return false;
                }
            }
            catch (Exception ex)
            {
                Util.Log(string.Format("{0} - {1}", ex.Message, ex.StackTrace));
                return false;
            }
        }

但这伴随着成功状态 200 的结果 - 这让我很困惑,因为我显然无法访问任何面向我 phone 的数据。

我建议您通过尝试打开到已知主机的套接字来检查连接 - 如果连接成功 - 您可以确定您有网络访问权限,否则您可以检查异常并处理它以显示错误连接。

public bool ActiveInternetConnectivity() {
    try {

        // connect to google on port 80, the HTTP port

        var socket = new Java.Net.Socket("www.google.com", 80);

        // the above would have thrown exception if failed, so we are good

        socket.Close();
        return true;

    } catch (Exception ex) {

        // check logcat to see why it failed, you could then catch and handle each exception independently ( time out, host unknown, end of stream, etc.. )

        System.Diagnostics.Debug.WriteLine(ex);

        // the connection has failed, return false
        return false;
    }

这只是一个想法,代码没有经过全面测试。

最终实施了以下似乎工作相当可靠的解决方案。您还可以对该方法强制可达性。

public static NetworkState GetNetworkState(this Context context, bool testReachability = false)
        {
            var result = NetworkState.NoNetwork;

            var connMgr = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);
            var activeNetwork = connMgr.ActiveNetworkInfo;

            if (activeNetwork == null || !activeNetwork.IsConnectedOrConnecting)
            {
                connMgr.Dispose();
                return NetworkState.NoNetwork;
            }

            if (activeNetwork.Type == ConnectivityType.Wifi && activeNetwork.IsConnected)
            {
                if (testReachability)
                {
                    if (CanReachServer())
                        result = NetworkState.WiFi;
                }
                else
                {
                    result = NetworkState.WiFi;
                }
            }
            else if (activeNetwork.Type == ConnectivityType.Mobile && activeNetwork.IsConnected)
            {
                if (testReachability)
                {
                    if (CanReachServer())
                        result = NetworkState.Mobile;
                }
                else
                {
                    result = NetworkState.Mobile;
                }
            }

            activeNetwork.Dispose();
            connMgr.Dispose();

            return result;
        }

        private static bool CanReachServer()
        {
            var uri = new Uri(Platform.ApiServerUrl).GetLeftPart(UriPartial.Authority);

            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    using (URL url = new URL(uri))
                    {
                        using (HttpURLConnection urlc = (HttpURLConnection)url.OpenConnection())
                        {
                            urlc.SetRequestProperty("User-Agent", "Android Application");
                            urlc.SetRequestProperty("Connection", "close");
                            urlc.ConnectTimeout = 6000;
                            urlc.ReadTimeout = 10000;
                            urlc.Connect();
                            bool result = urlc.ResponseCode == HttpStatus.Ok;
                            urlc.Disconnect();
                            return result;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Util.Log(string.Format("{0} - {1}", ex.Message, ex.StackTrace));
                    return false;
                }
            });
            task.Wait();
            return task.Result;
        }
    }