2016-02-11 1 views
0

я в настоящее время имеющий один специальный случай использования, что я совсем запутался, как решить.Android - проверка, если соединение данных на самом деле работает

Мы проверяли для подключения к Интернету с ConnectivityService, который имеет те ConnectivityType.Wifi/ConnectivityType.Mobile со свойством, если он подключен /подключение. Это все хорошо, пока вы не столкнетесь с следующим случаем:

  • У вас есть данные на телефоне.
  • Соединение для передачи данных подключено.
  • Однако вы не платите за счет данных, так что вы не можете делать какие-либо передачи данных.
  • (убедитесь, что 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 - что делает меня очень запутанным, поскольку я явно не могу получить доступ к каким-либо данным, ориентированным на мой телефон.

+0

Вы должны проверить эту https://developer.xamarin.com/recipes/ios/network/reachability/detect_if_network_is_available/ и это https://developer.xamarin.com/recipes/android/networking/networkinfo/ detect_network_connection/ – Rohit5k2

+0

@ Rohit5k2 спасибо, конечно, я видел это раньше, также первый относится к iOS, а не к Android :), и, как я уже говорил, я сделал материал ConnectivityService. –

+0

Вторая ссылка для android – Rohit5k2

ответ

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

Я предлагаю вам проверить соединение, пытаясь открыть сокет для известного хоста - если соединение выполнено успешно - вы можете быть уверены, что у вас есть доступ к сети, иначе вы можете проверить Exception и обработать его, чтобы показать соединение с ошибкой ,

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

Это просто идея, коды не полностью протестированы.

+0

я на самом деле пытался это раньше, но получаю следующее исключение в Xamarin: в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000b] в/Users/строитель/данных/полосы движения/2185/53fce373/источник/моно/MCS/класс /corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:61 \ п на Android.Runtime.JNIEnv.CallNonvirtualVoidMethod (IntPtr jobject, IntPtr JClass, IntPtr jmethod, Android.Runtime.JValue * Parms) [0x00084] в/Users/строитель /data/lanes/2185/53fce373/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1029 \ п на Android.Runtime.JNIEnv.FinishCreateInstance –

+0

@JakubHolovsky: Укажите, откуда ошибка имеет место. ! – Vaikesh

+0

Случается, когда вы создаете сокет var socket = новый Java.Net.Socket («www.google.com», 80); –

Смежные вопросы