0

I want to listen for when the GoogleTV device is disconnected and then display a pop up warning.

I thought I had achieved this by the below code, but then discovered that I am only warned about the disconnection when the device's ethernet cable is disconnected: i.e. LAN. I am not alerted when the router's input ethernet cable is disconnected: i.e. WAN.

I have discovered that when disconnecting the LAN cable, the GTV device will lose its IP address, but when disconnecting the WAN cable, the GTV device WILL still have an IP address - that is why it I am not alerted that the app lost a connection.

So how do I check when a GoogleTV device is no longer connected to a WAN? What do I need to add to the below code to do that?

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());
}
jaxim
  • 515
  • 1
  • 9
  • 20
  • `return InetAddress.getByName("google.com").isReachable(10*1000);` :) – Nikola Despotoski Jul 30 '13 at 02:57
  • isReachable() is fine if I want to know if there is an internet connection right NOW. But I also want to be alerted when the internet is lost or is re-obtained. That is why I use the registerReceiver() method mentioned above. With the isReachable() method, I guess I could make a timer to constantly ping "google.com", but that seems like it would NOT be a best practice. – jaxim Jul 30 '13 at 17:45
  • Did you try `isConnectedOrConnecting()` and `isFailOver()`? – Nikola Despotoski Jul 30 '13 at 18:22
  • That's would still just test the connection at a particular time. Is there nothing that dispatches an event when the WAN connection is lost like when the LAN connection is lost? – jaxim Jul 31 '13 at 13:47
  • I've posted an answer below. Regarding this, you can create a Handler and run the checks recursively, and check the connection at any time, thus you can create your own broadcast receiver, similarly to the `CONNECTIVITY_ACTION` – Nikola Despotoski Jul 31 '13 at 15:33
  • Please read my edit. I added the approach I proposed above. – Nikola Despotoski Jul 31 '13 at 20:22

1 Answers1

0

Register CONNECTIVITY_ACTION for BroadcastReceiver

  1. There are two options you can try:

    • Use the Context that BroadcastReceiver is passed with to get the ConnectivityManager and get current info about any active network
    • Use parcerable extras sent to the Intent
  2. Get the detailed state of the active network obtained from any of the options in point 1

public class LANConnectionReceiver extends 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;

                }
            }
    }



}

Note that, we are not interested in the type of the network, since we are interested if the TV has WAN access, that's why I put the condition info.getType()==ConnectivityManager.TYPE_ETHERNET as optional.

Edit: In above comments I mentioned recursively checking for network without blocking the app.

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);
                    }});
            }
Nikola Despotoski
  • 49,966
  • 15
  • 119
  • 148
  • This does not work either. This solution works for LAN disconnects but does not work for WAN disconnects. – jaxim Jul 31 '13 at 15:53
  • 1
    By the way, if someone happens to this question and is interested in implementing the BroadcastReceiver solution, the Manifest file will need to be changed to add an intent in order for this to work. @see http://stackoverflow.com/questions/15698790/broadcast-receiver-for-checking-internet-connection-in-android-app – jaxim Jul 31 '13 at 15:54
  • I've edit my answer with the other approach I mentioned above with recursive handler call. You can arrange arguments and method modifier as you wish. – Nikola Despotoski Jul 31 '13 at 16:28