2013-07-30 3 views
0

Я хочу слушать, когда устройство GoogleTV отключено, а затем отобразится всплывающее предупреждение.Слушайте, когда Android/GoogleTV отключен от WAN

Я думал, что достиг этого по приведенному ниже коду, но потом обнаружил, что я только предупреждал об отключении, когда кабель Ethernet-кабеля устройства отключен: например, LAN. Я не предупреждаю, когда сетевой кабель маршрутизатора отключен: т. Е. WAN.

Я обнаружил, что при отсоединении кабеля LAN устройство GTV потеряет свой IP-адрес, но при отключении кабеля WAN устройство GTV будет иметь IP-адрес, поэтому я не предупрежден о том, что приложение потеряло соединение.

Как я могу проверить, когда устройство GoogleTV больше не подключено к глобальной сети? Что мне нужно добавить к приведенному ниже коду для этого?

startListeningToNetwork(); 
private void startListeningToNetwork() { 
    if(_networkStateReceiver == null){ 
     //Listen for when the network changes. If app loses internet before webView has loaded, then display error message. 
     _networkStateReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
      if(!isConnected()){ 
       showNetworkErrorDialog(); 
      } else { 
         closeNetworkError(); 
      } 
      } 

     }; 


     IntentFilter networkFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); 

     getActivity().registerReceiver(_networkStateReceiver, networkFilter); 
    } 

} 
private boolean isConnected() { 
    ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); 
    Toast.makeText(getActivity(), "isConnected? " + (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected()) , Toast.LENGTH_SHORT).show(); 
    return (cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected()); 
} 
+0

'вернуть InetAddress.getByName ("google.com") isReachable (10 * 1000);.' :) –

+0

isReachable() это хорошо, если я хочу знать, если есть подключение к Интернету прямо сейчас. Но я также хочу, чтобы вас предупреждали, когда Интернет потерян или получил повторное получение. Вот почему я использую метод registerReceiver(), упомянутый выше. С методом isReachable(), я думаю, я мог бы сделать таймер, чтобы постоянно пинговать «google.com», но похоже, что это не будет лучшей практикой. – jaxim

+0

Вы пытались использовать 'isConnectedOrConnecting()' и 'isFailOver()'? –

ответ

0

Регистрация CONNECTIVITY_ACTION для BroadcastReceiver

  1. Есть два варианта, вы можете попробовать:

    • Используйте Context, что BroadcastReceiver передается с, чтобы получить ConnectivityManager и получить текущую информацию о любой активная сеть
    • Использовать парциальные extras s лор на Intent
  2. Получить подробную состояние активной сети, полученной из любой из вариантов в пункте 1

общественный класс LANConnectionReceiver простирается BroadcastReceiver {

@Override 
    public void onReceive(Context context, Intent i) { 

      NetworkInfo info = (NetworkInfo)i.getParcelableExtra(ConnectivityManager.EXTRA_EXTRA_INFO); 
      /*or use the context to get the connection manager whenever the broadcast is sent to this receiver 
      * ConnectivityManager conmng = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
       NetworkInfo activeNetwork = conmng.getActiveNetworkInfo(); 
      */ 
      Log.d("ConnectionReceiver", "State=" + info.getDetailedState()); 
      if(info.getType() ==ConnectivityManager.TYPE_ETHERNET){ //optional, we are interested in case when it looses WAN 
       switch(info.getDetailedState()){ 
       case AUTHENTICATING: 
        break; 
       case BLOCKED: 
        break; 
       case CAPTIVE_PORTAL_CHECK: 
        break; 
       case CONNECTED: 
        break; 
       case CONNECTING: 
        break; 
       case DISCONNECTED: 
        break; 
       case DISCONNECTING: 
        break; 
       case FAILED: 
        break; 
       case IDLE: 
        break; 
       case OBTAINING_IPADDR: 
        break; 
       case SCANNING: 
        break; 
       case SUSPENDED: 
        break; 
       case VERIFYING_POOR_LINK: 
        break; 
       default: 
        break; 

       } 
      } 
    } 



} 

Обратите внимание, что , нас не интересует тип сети, поскольку нам интересно, имеет ли телевидение доступ к WAN, поэтому я поместил условие info.getType()==ConnectivityManager.TYPE_ETHERNET в качестве дополнительного.

Редактировать: В предыдущих комментариях я упомянул рекурсивную проверку сети, не блокируя приложение.

public void listenForConnection(final Context c, final Handler h){ 
       h.postAtFrontOfQueue(new Runnable(){ 

        @Override 
        public void run() { 
         ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE); 
         NetworkInfo networkInfo = cm.getActiveNetworkInfo(); 
         if(networkInfo!=null && networkInfo.isConnectedOrConnecting()){ 
          Intent i = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); 
          i.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, networkInfo.getType()); 
          i.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 
          i.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, networkInfo.isFailover()); 
          i.putExtra("MY_CUSTOM_KEY_HAS_WAN", true); 
          c.sendBroadcast(i); 
         }else { 
          //do something else 
         } 
         h.postDelayed(this, 100); 
        }}); 
      } 
+0

Это тоже не работает. Это решение работает для разъединений LAN, но не работает для разъединений WAN. – jaxim

+1

Кстати, если кто-то сталкивается с этим вопросом и заинтересован в реализации решения BroadcastReceiver, файл манифеста необходимо будет изменить, чтобы добавить намерение, чтобы это работало. @see http://stackoverflow.com/questions/15698790/broadcast-receiver-for-checking-internet-connection-in-android-app – jaxim

+0

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