Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 理解安卓&x27;s Wifi状态_Android_Networking - Fatal编程技术网

Android 理解安卓&x27;s Wifi状态

Android 理解安卓&x27;s Wifi状态,android,networking,Android,Networking,我需要检查我的设备是否连接到wifi网络。但是发生的事情让我困惑。以下是复制的步骤: 注册接收者 因此,我向操作WifiManager.NETWORK\u STATE\u CHANGED\u action)注册了一个接收器: 收到 这就是我接收事件的方式 private class ConnectivityBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context co

我需要检查我的设备是否连接到wifi网络。但是发生的事情让我困惑。以下是复制的步骤:

注册接收者 因此,我向操作
WifiManager.NETWORK\u STATE\u CHANGED\u action)
注册了一个接收器:

收到 这就是我接收事件的方式

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());
    }
}
用户输入
  • 我启动应用程序,从上面向下拉Android菜单,打开wifi设置(按住wifi符号),然后连接到wifi网络。然后我返回到我的应用程序
  • 我启动应用程序,从上面拉下Android菜单,从快速设置中激活wifi。然后我返回到我的应用程序。我的设备会自动连接到已知的wifi
  • 输出 首先,我收到一些关于
    连接
    身份验证
    的事件。这里一切似乎都很正常

    但是在一次设置过程中,我连续四次得到这个输出:

    onReceive: Broadcast android.net.wifi.STATE_CHANGE
    NetworkInfo.State: CONNECTED
    NetworkInfo.DetailedState: CONNECTED
    SupplicantState: COMPLETED
    DetailedStateOfSupplicant: OBTAINING_IPADDR
    
  • 为什么会触发这四个事件
  • 根据文档,请求者状态
    COMPLETED
    映射到
    获取\u IPADDR
    似乎符合逻辑:

    请求状态已完成:
    此状态表示请求者已完成其处理 对于关联阶段,该数据连接已完全断开 配置。但是,请注意,可能没有任何IP地址 尚未与连接关联。通常,DHCP请求需要 此时发送以获取地址

  • 但是,如果我的设备实际上只是获取其IP地址,为什么网络信息状态甚至详细状态都设置为“已连接”

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

  • 来源
    • 可以找到
      NetworkInfo.State
      NetworkInfo.DetailedState
      的概述
    • 可以找到
      请求状态
      的概述

    使用以下类别检查网络状态:

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

    使用以下类别检查网络状态:

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

    好像有个虫子。。。由于新建立的wifi连接,在wifi事件发生后立即调用
    isConnectedWifi()
    ,然后
    getActiveNetworkInfo()
    返回null,因为Android无法在该时间切换默认值。在这种情况下,您必须实现网络状态更改侦听器。这个类无法处理它。似乎有一个bug。。。由于新建立的wifi连接,在wifi事件发生后立即调用
    isConnectedWifi()
    ,然后
    getActiveNetworkInfo()
    返回null,因为Android无法在该时间切换默认值。在这种情况下,您必须实现网络状态更改侦听器。这个类无法处理它。