【问题标题】:Listen to when Android/GoogleTV is disconnected from a WAN在 Android/GoogleTV 与 WAN 断开连接时收听
【发布时间】:2013-08-01 00:27:55
【问题描述】:

我想在 GoogleTV 设备断开连接时收听,然后显示弹出警告。

我以为我已经通过下面的代码实现了这一点,但后来发现我只在设备的以太网电缆断开时才收到断开连接的警告:即 LAN。当路由器的输入以太网电缆断开连接时,我不会收到警报:即 WAN。

我发现在断开 LAN 电缆时,GTV 设备会丢失其 IP 地址,但在断开 WAN 电缆时,GTV 设备仍将有一个 IP 地址 - 这就是为什么我没有收到应用程序提醒的原因失去连接。

那么如何检查 GoogleTV 设备何时不再连接到 WAN?我需要在下面的代码中添加什么来做到这一点?

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

【问题讨论】:

  • return InetAddress.getByName("google.com").isReachable(10*1000); :)
  • 如果我想知道现在是否有互联网连接,isReachable() 很好。但我也想在互联网丢失或重新获得时收到警报。这就是我使用上面提到的 registerReceiver() 方法的原因。使用 isReachable() 方法,我想我可以制作一个计时器来不断 ping “google.com”,但这似乎不是最佳做法。
  • 你试过isConnectedOrConnecting()isFailOver()吗?
  • 那仍然只是在特定时间测试连接。当 WAN 连接丢失时,没有什么会像 LAN 连接丢失一样调度事件吗?
  • 我在下面发布了一个答案。对此,您可以创建一个 Handler 并递归地运行检查,随时检查连接,这样您就可以创建自己的广播接收器,类似于CONNECTIVITY_ACTION

标签: android google-tv


【解决方案1】:

注册CONNECTIVITY_ACTION广播接收器

  1. 您可以尝试两种选择:

    • 使用传递BroadcastReceiverContext 获取ConnectivityManager 并获取有关任何活动网络的当前信息
    • 使用可解析的extras 发送到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 设置为可选的原因。

编辑:在上面的 cmets 中,我提到了递归检查网络而不阻塞应用程序。

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

【讨论】:

  • 这也不起作用。此解决方案适用于 LAN 断开连接,但不适用于 WAN 断开连接。
  • 顺便说一下,如果有人遇到这个问题并且有兴趣实现 BroadcastReceiver 解决方案,则需要更改 Manifest 文件以添加意图以使其正常工作。 @见stackoverflow.com/questions/15698790/…
  • 我已经用上面提到的递归处理程序调用的另一种方法编辑了我的答案。您可以根据需要安排参数和方法修饰符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多