Android - 检查数据连接是否确实有效

时间:2016-02-11 13:46:32

标签: android xamarin xamarin.android

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

我们一直在检查与 ConnectivityService 的互联网连接,其中包含 ConnectivityType.Wifi / ConnectivityType.Mobile ,如果是< strong>连接/连接。在遇到以下情况之前,这一切都很好:

  • 您的手机已启用数据。
  • 已连接数据连接。
  • 然而您不需要为数据帐单付款,因此无法进行任何数据传输。
  • (确保尝试使用时关闭wifi)

我以为我只会检查如下:

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的结果 - 这让我很困惑,因为我显然无法访问手机上的任何数据。

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

结束实施以下似乎非常可靠的解决方案。您还可以对该方法强制实施可访问性。

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