检测Android上的networking连接types

如何检测Android上的networking连接types?

它是通过ConnectivityManager.getActiveNetworkInfo().getType() ,并且是仅限于Wifi和移动的答案吗?

如果问题是要find手机的networking是否连接并且速度足够满足您的要求,则必须处理由getSubType()返回的所有networkingtypes。

我花了一两个小时的时间来研究和写这个课程,完全是这样做的,我想我会把它分享给那些可能会发现它有用的人。

这是课堂的要点 ,所以你可以把它分开编辑。

 package com.emil.android.util; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; /** * Check device's network connectivity and speed * @author emil http://stackoverflow.com/users/220710/emil * */ public class Connectivity { /** * Get the network info * @param context * @return */ public static NetworkInfo getNetworkInfo(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); return cm.getActiveNetworkInfo(); } /** * Check if there is any connectivity * @param context * @return */ public static boolean isConnected(Context context){ NetworkInfo info = Connectivity.getNetworkInfo(context); return (info != null && info.isConnected()); } /** * Check if there is any connectivity to a Wifi network * @param context * @param type * @return */ public static boolean isConnectedWifi(Context context){ NetworkInfo info = Connectivity.getNetworkInfo(context); return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI); } /** * Check if there is any connectivity to a mobile network * @param context * @param type * @return */ public static boolean isConnectedMobile(Context context){ NetworkInfo info = Connectivity.getNetworkInfo(context); return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE); } /** * Check if there is fast connectivity * @param context * @return */ public static boolean isConnectedFast(Context context){ NetworkInfo info = Connectivity.getNetworkInfo(context); return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype())); } /** * Check if the connection is fast * @param type * @param subType * @return */ 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 /* * Above API level 7, make sure to set android:targetSdkVersion * to appropriate level to use these */ 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; } } } 

另外请确保将此权限添加到您的AndroidManifest.xml

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> 

networking速度的来源包括维基百科& http://3gstore.com/page/78_what_is_evdo_mobile_broadband.html

您可以使用getSubtype()获取更多详细信息。 请在此处查看幻灯片9: http : //dl.google.com/io/2009/pres/W_0300_CodingforLife-BatteryLifeThatIs.pdf

 ConnectivityManager mConnectivity = null; TelephonyManager mTelephony = null; // Skip if no connection, or background data disabled NetworkInfo info = mConnectivity.getActiveNetworkInfo(); if (info == null || !mConnectivity.getBackgroundDataSetting()) { return false; } // Only update if WiFi or 3G is connected and not roaming int netType = info.getType(); int netSubtype = info.getSubtype(); if (netType == ConnectivityManager.TYPE_WIFI) { return info.isConnected(); } else if (netType == ConnectivityManager.TYPE_MOBILE && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS && !mTelephony.isNetworkRoaming()) { return info.isConnected(); } else { return false; } 

此外,请查看Emil的答案,以便更详细地了解这一点。

获得更精确的(和用户友好的)有关连接types的信息。 您可以使用此代码(从TelephonyManager.java中的@hide方法派生而来)。

此方法返回描述当前连接types的string。
即:“WIFI”,“2G”,“3G”,“4G”,“ – ”(未连接)或“?” (未知)

备注:此代码需要API 15+,但是您可以使用int而不是const来轻松支持旧版本。 (见代码注释)

 public static String getNetworkClass(Context context) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); if(info==null || !info.isConnected()) return "-"; //not connected if(info.getType() == ConnectivityManager.TYPE_WIFI) return "WIFI"; if(info.getType() == ConnectivityManager.TYPE_MOBILE){ int networkType = info.getSubtype(); switch (networkType) { case TelephonyManager.NETWORK_TYPE_GPRS: case TelephonyManager.NETWORK_TYPE_EDGE: case TelephonyManager.NETWORK_TYPE_CDMA: case TelephonyManager.NETWORK_TYPE_1xRTT: case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11 return "2G"; case TelephonyManager.NETWORK_TYPE_UMTS: case TelephonyManager.NETWORK_TYPE_EVDO_0: case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_HSDPA: case TelephonyManager.NETWORK_TYPE_HSUPA: case TelephonyManager.NETWORK_TYPE_HSPA: case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9 : replace by 14 case TelephonyManager.NETWORK_TYPE_EHRPD: //api<11 : replace by 12 case TelephonyManager.NETWORK_TYPE_HSPAP: //api<13 : replace by 15 return "3G"; case TelephonyManager.NETWORK_TYPE_LTE: //api<11 : replace by 13 return "4G"; default: return "?"; } } return "?"; } 

@埃米尔上面的答案是辉煌的。

小增加:理想情况下,我们应该使用TelephonyManager来检测networkingtypes。 所以上面应该改为:

 /** * Check if there is fast connectivity * @param context * @return */ public static boolean isConnectedFast(Context context){ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo(); TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(), tm.getNetworkType())); } 

Emil Davtyan的回答是很好的,但是networkingtypes已经被添加了,在他的回答中没有被解释。 所以, isConnectionFast(int type, int subType)可能会返回false时,它应该是true。

这是一个修改后的类,它使用reflection来考虑以后的API中添加的networkingtypes:

 import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * <p>Utility methods to check the current network connection status.</p> * * <p>This requires the caller to hold the permission * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.</p> */ public class NetworkUtils { /** The absence of a connection type. */ public static final int TYPE_NONE = -1; /** Unknown network class. */ public static final int NETWORK_CLASS_UNKNOWN = 0; /** Class of broadly defined "2G" networks. */ public static final int NETWORK_CLASS_2_G = 1; /** Class of broadly defined "3G" networks. */ public static final int NETWORK_CLASS_3_G = 2; /** Class of broadly defined "4G" networks. */ public static final int NETWORK_CLASS_4_G = 3; /** * Returns details about the currently active default data network. When connected, this network * is the default route for outgoing connections. You should always check {@link * NetworkInfo#isConnected()} before initiating network traffic. This may return {@code null} * when there is no default network. * * @return a {@link NetworkInfo} object for the current default network or {@code null} if no * network default network is currently active * * This method requires the call to hold the permission * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}. * @see ConnectivityManager#getActiveNetworkInfo() */ public static NetworkInfo getInfo(Context context) { return ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)) .getActiveNetworkInfo(); } /** * Reports the current network type. * * @return {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} , * {@link ConnectivityManager#TYPE_WIMAX}, {@link ConnectivityManager#TYPE_ETHERNET}, {@link * ConnectivityManager#TYPE_BLUETOOTH}, or other types defined by {@link ConnectivityManager}. * If there is no network connection then -1 is returned. * @see NetworkInfo#getType() */ public static int getType(Context context) { NetworkInfo info = getInfo(context); if (info == null || !info.isConnected()) { return TYPE_NONE; } return info.getType(); } /** * Return a network-type-specific integer describing the subtype of the network. * * @return the network subtype * @see NetworkInfo#getSubtype() */ public static int getSubType(Context context) { NetworkInfo info = getInfo(context); if (info == null || !info.isConnected()) { return TYPE_NONE; } return info.getSubtype(); } /** Returns the NETWORK_TYPE_xxxx for current data connection. */ public static int getNetworkType(Context context) { return ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)) .getNetworkType(); } /** Check if there is any connectivity */ public static boolean isConnected(Context context) { return getType(context) != TYPE_NONE; } /** Check if there is any connectivity to a Wifi network */ public static boolean isWifiConnection(Context context) { NetworkInfo info = getInfo(context); if (info == null || !info.isConnected()) { return false; } switch (info.getType()) { case ConnectivityManager.TYPE_WIFI: return true; default: return false; } } /** Check if there is any connectivity to a mobile network */ public static boolean isMobileConnection(Context context) { NetworkInfo info = getInfo(context); if (info == null || !info.isConnected()) { return false; } switch (info.getType()) { case ConnectivityManager.TYPE_MOBILE: return true; default: return false; } } /** Check if the current connection is fast. */ public static boolean isConnectionFast(Context context) { NetworkInfo info = getInfo(context); if (info == null || !info.isConnected()) { return false; } switch (info.getType()) { case ConnectivityManager.TYPE_WIFI: case ConnectivityManager.TYPE_ETHERNET: return true; case ConnectivityManager.TYPE_MOBILE: int networkClass = getNetworkClass(getNetworkType(context)); switch (networkClass) { case NETWORK_CLASS_UNKNOWN: case NETWORK_CLASS_2_G: return false; case NETWORK_CLASS_3_G: case NETWORK_CLASS_4_G: return true; } default: return false; } } private static int getNetworkClassReflect(int networkType) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method getNetworkClass = TelephonyManager.class.getDeclaredMethod("getNetworkClass", int.class); if (!getNetworkClass.isAccessible()) { getNetworkClass.setAccessible(true); } return (int) getNetworkClass.invoke(null, networkType); } /** * Return general class of network type, such as "3G" or "4G". In cases where classification is * contentious, this method is conservative. */ public static int getNetworkClass(int networkType) { try { return getNetworkClassReflect(networkType); } catch (Exception ignored) { } switch (networkType) { case TelephonyManager.NETWORK_TYPE_GPRS: case 16: // TelephonyManager.NETWORK_TYPE_GSM: case TelephonyManager.NETWORK_TYPE_EDGE: case TelephonyManager.NETWORK_TYPE_CDMA: case TelephonyManager.NETWORK_TYPE_1xRTT: case TelephonyManager.NETWORK_TYPE_IDEN: return NETWORK_CLASS_2_G; case TelephonyManager.NETWORK_TYPE_UMTS: case TelephonyManager.NETWORK_TYPE_EVDO_0: case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_HSDPA: case TelephonyManager.NETWORK_TYPE_HSUPA: case TelephonyManager.NETWORK_TYPE_HSPA: case TelephonyManager.NETWORK_TYPE_EVDO_B: case TelephonyManager.NETWORK_TYPE_EHRPD: case TelephonyManager.NETWORK_TYPE_HSPAP: case 17: // TelephonyManager.NETWORK_TYPE_TD_SCDMA: return NETWORK_CLASS_3_G; case TelephonyManager.NETWORK_TYPE_LTE: case 18: // TelephonyManager.NETWORK_TYPE_IWLAN: return NETWORK_CLASS_4_G; default: return NETWORK_CLASS_UNKNOWN; } } private NetworkUtils() { throw new AssertionError(); } } 

您可以使自定义方法来完成此任务。

  public String getNetworkClass(Context context) { TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); int networkType = mTelephonyManager.getNetworkType(); switch (networkType) { case TelephonyManager.NETWORK_TYPE_GPRS: case TelephonyManager.NETWORK_TYPE_EDGE: case TelephonyManager.NETWORK_TYPE_CDMA: case TelephonyManager.NETWORK_TYPE_1xRTT: case TelephonyManager.NETWORK_TYPE_IDEN: return "2G"; case TelephonyManager.NETWORK_TYPE_UMTS: case TelephonyManager.NETWORK_TYPE_EVDO_0: case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_HSDPA: case TelephonyManager.NETWORK_TYPE_HSUPA: case TelephonyManager.NETWORK_TYPE_HSPA: case TelephonyManager.NETWORK_TYPE_EVDO_B: case TelephonyManager.NETWORK_TYPE_EHRPD: case TelephonyManager.NETWORK_TYPE_HSPAP: return "3G"; case TelephonyManager.NETWORK_TYPE_LTE: return "4G"; default: return "Unknown"; } } 

除了埃米尔的回答之外,我想再添加一个方法来检查你是否真正拥有互联网接入,因为你的手机上的数据可能已经closures了。

 public static boolean hasInternetAccess(Context c){ TelephonyManager tm = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE); if(isConnected(c) && tm.getDataState() == TelephonyManager.DATA_CONNECTED) return true; else return false; } 

请注意,这仅用于检查蜂窝数据连接,如果连接了WiFi,将返回false,因为WiFi连接时蜂窝数据已closures。

 String active_network = ((ConnectivityManager) .getSystemService(Context.CONNECTIVITY_SERVICE)) .getActiveNetworkInfo().getSubtypeName(); 

应该让你的networking名称

你可以这样检查

 public void checktype() { ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (activeNetwork != null) { // connected to the internet if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) { // connected to wifi Toast.makeText(this, activeNetwork.getTypeName(), Toast.LENGTH_SHORT).show(); } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { // connected to the mobile provider's data plan Toast.makeText(this, activeNetwork.getTypeName(), Toast.LENGTH_SHORT).show(); } } } 

目前只支持MOBILE和WIFI。 看看和人类可读的types的function 。