Определение типа сетевого подключения на Android
Как вы определяете тип сетевого подключения на Android?
это ConnectivityManager.getActiveNetworkInfo().getType()
, и ответ ограничен Wi-Fi и мобильным телефоном?
10 ответов:
Если проблема заключается в том, чтобы найти, подключена ли сеть телефона и достаточно быстро, чтобы удовлетворить ваши требования, вы должны обрабатывать все типы сетей, возвращаемые
getSubType()
.здесь суть класс, так что вы можете скопировать его и отредактировать его.
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>
источники для сетевых скоростей включают Википедию & 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; }
кроме того, пожалуйста, проверьте ответ Эмиля для более подробного погружения в это.
чтобы получить более точную (и удобную для пользователя) информацию о типе соединения. Вы можете использовать этот код (производный от метода @hide в TelephonyManager.java).
этот метод возвращает строку, описывающую тип текущего подключения.
т. е. один из: "WIFI"," 2G"," 3G"," 4G", " - "(не подключен) или"?"(неизвестно)Примечание: этот код требует API 25+, но вы можете легко поддерживать более старые версии, используя 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 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: //api<25 : replace by 17 return "3G"; case TelephonyManager.NETWORK_TYPE_LTE: //api<11 : replace by 13 case TelephonyManager.NETWORK_TYPE_IWLAN: //api<25 : replace by 18 case 19: //LTE_CA return "4G"; default: return "?"; } } return "?"; }
@Эмиль ответ выше блестящий.
небольшое дополнение: в идеале мы должны использовать TelephonyManager для обнаружения типов сетей. Поэтому вместо этого следует читать:
/** * 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())); }
ответ от Эмиля Давтяна хорош, но были добавлены типы сетей, которые не учитываются в его ответе. Итак,
isConnectionFast(int type, int subType)
может возвращать false, когда это должно быть true.вот модифицированный класс, который использует отражение для учета добавленных типов сети в более поздних API:
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"; } }
в дополнение к удивительному ответу Эмиля я хотел бы добавить еще один метод, чтобы проверить, действительно ли у вас есть доступ в Интернет, поскольку вы можете отключить данные на своем телефоне.
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; }
обратите внимание, что это только для проверки, если есть сотовое соединение для передачи данных и вернет false, если у вас подключен Wi-Fi, так как сотовые данные отключены при подключении Wi-Fi.
String active_network = ((ConnectivityManager) .getSystemService(Context.CONNECTIVITY_SERVICE)) .getActiveNetworkInfo().getSubtypeName();
должен получить вам имя сети
вы можете проверить, как это
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(); } } }
В настоящее время поддерживаются только мобильные и WIFI. Взгляните и человек читаемый функции типа.