2017-09-13 66 views
0

我需要检查我的设备是否连接到WiFi网络。但是发生的事件让我感到困惑。下面是步骤来重现:了解Android的Wifi状态

registerReceiver

所以我注册了一个接收器与行动WifiManager.NETWORK_STATE_CHANGED_ACTION)

private void registerReceiver() { 
    Log.v(TAG, "registerReceiver"); 

    final IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 

    broadcastReceiver = new ConnectivityBroadcastReceiver(); 
    context.registerReceiver(broadcastReceiver, intentFilter); 
} 

的onReceive

这就是我如何接收的事件。

private class ConnectivityBroadcastReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.v("Broadcast", "onReceive: " + intent.getAction()); 
     final NetworkInfo networkInfo = 
       intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 

     if (networkInfo != null) { 
      final NetworkInfo.State state = networkInfo.getState(); 
      final NetworkInfo.DetailedState detailedState = networkInfo.getDetailedState(); 

      Log.d(TAG, "NetworkInfo.State: " + state); 
      Log.d(TAG, "NetworkInfo.DetailedState: " + detailedState); 
     } 

     final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 
     final WifiInfo wifiInfo = wifiManager.getConnectionInfo(); 

     final SupplicantState supplicantState = wifiInfo.getSupplicantState(); 
     final NetworkInfo.DetailedState detailedState = wifiInfo.getDetailedStateOf(supplicantState); 

     Log.d(TAG, "SupplicantState: " + supplicantState.toString()); 
     Log.d(TAG, "DetailedStateOfSupplicant: " + detailedState.toString()); 
    } 
} 

用户输入

  1. 我启动应用程序,拉Android的菜单从上往下,开wifi设置(保持的WiFi标志),并连接到WiFi网络。然后我回到我的应用程序。

  • 我启动应用程序,从快速设置拉Android的菜单从上面,活性的WiFi下来。然后我回到我的应用程序。我的设备自动连接到已知的无线网络。
  • 输出

    首先,我收到有关CONNECTINGAUTHENTICATING一些事件。在这里一切似乎都很正常。

    但后来我在一个设置获得连胜这个输出四次

    onReceive: Broadcast android.net.wifi.STATE_CHANGE 
    NetworkInfo.State: CONNECTED 
    NetworkInfo.DetailedState: CONNECTED 
    SupplicantState: COMPLETED 
    DetailedStateOfSupplicant: OBTAINING_IPADDR 
    
    1. 为什么这四个事件触发?

    即请求者状态COMPLETED被映射到OBTAINING_IPADDR根据文档似乎逻辑:

    SupplicantState完成:
    此状态表示请求者已经完成了其处理 用于关联相和数据连接完全配置为 。但请注意,可能没有任何与该连接相关联的IP地址 。通常,此时需要发送DHCP请求 以获取地址。

  • 偏偏是网络信息的状态,甚至详细的状态设置为CONNECTED如果我的设备实际上只是获得它的IP地址?

  • 如何确保我的设备“真正”连接,换句话说,我如何知道设备何时最终获得IP地址以及何时可以使用网络?有更好的行动,我可以注册吗?

  • 来源

    • NetworkInfo.StateNetworkInfo.DetailedState综述可以发现here
    • SupplicantState的概述可以找到here。使用下面的类

    回答

    1

    检查网络状态:

    public class Connectivity { 
        public static NetworkInfo getNetworkInfo(Context context){ 
         ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
         return cm.getActiveNetworkInfo(); 
        } 
    
    
        public static boolean isConnected(Context context){ 
         NetworkInfo info = Connectivity.getNetworkInfo(context); 
         return (info != null && info.isConnected()); 
        } 
    
        public static boolean isConnectedWifi(Context context){ 
         NetworkInfo info = Connectivity.getNetworkInfo(context); 
         return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI); 
        } 
    
    
        public static boolean isConnectedMobile(Context context){ 
         NetworkInfo info = Connectivity.getNetworkInfo(context); 
         return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE); 
        } 
    
    
        public static boolean isConnectedFast(Context context){ 
         NetworkInfo info = Connectivity.getNetworkInfo(context); 
         return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype())); 
        } 
    
    
        public static boolean isConnectionFast(int type, int subType){ 
         if(type== ConnectivityManager.TYPE_WIFI){ 
          return true; 
         }else if(type==ConnectivityManager.TYPE_MOBILE){ 
          switch(subType){ 
           case TelephonyManager.NETWORK_TYPE_1xRTT: 
            return false; // ~ 50-100 kbps 
           case TelephonyManager.NETWORK_TYPE_CDMA: 
            return false; // ~ 14-64 kbps 
           case TelephonyManager.NETWORK_TYPE_EDGE: 
            return false; // ~ 50-100 kbps 
           case TelephonyManager.NETWORK_TYPE_EVDO_0: 
            return true; // ~ 400-1000 kbps 
           case TelephonyManager.NETWORK_TYPE_EVDO_A: 
            return true; // ~ 600-1400 kbps 
           case TelephonyManager.NETWORK_TYPE_GPRS: 
            return false; // ~ 100 kbps 
           case TelephonyManager.NETWORK_TYPE_HSDPA: 
            return true; // ~ 2-14 Mbps 
           case TelephonyManager.NETWORK_TYPE_HSPA: 
            return true; // ~ 700-1700 kbps 
           case TelephonyManager.NETWORK_TYPE_HSUPA: 
            return true; // ~ 1-23 Mbps 
           case TelephonyManager.NETWORK_TYPE_UMTS: 
            return true; // ~ 400-7000 kbps 
           case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11 
            return true; // ~ 1-2 Mbps 
           case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9 
            return true; // ~ 5 Mbps 
           case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13 
            return true; // ~ 10-20 Mbps 
           case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8 
            return false; // ~25 kbps 
           case TelephonyManager.NETWORK_TYPE_LTE: // API level 11 
            return true; // ~ 10+ Mbps 
           // Unknown 
           case TelephonyManager.NETWORK_TYPE_UNKNOWN: 
           default: 
            return false; 
          } 
         }else{ 
          return false; 
         } 
        } 
    } 
    
    +0

    似乎是一个错误......当你调用'isConnectedWifi()'右后发生的,因为一个新建立的WiFi连接的无线网络事件,那么'getActiveNetworkInfo()'返回null,因为Android在那段时间无法切换默认值 – winklerrr