Wykrywanie typu połączenia sieciowego na Androidzie
Jak wykryć typ połączenia sieciowego na Androidzie?
Czy to przez ConnectivityManager.getActiveNetworkInfo().getType()
, a czy odpowiedź jest ograniczona do Wifi i telefonu komórkowego?
10 answers
Jeśli problem polega na sprawdzeniu, czy sieć telefonu jest podłączona i wystarczająco szybka, aby spełnić twoje wymagania, musisz obsłużyć wszystkie typy sieci zwracane przez getSubType()
.
Zajęło mi godzinę lub dwie, aby zbadać i napisać tę klasę, aby zrobić dokładnie to, i pomyślałem, że podzielę się nią z innymi, którzy mogą uznać ją za przydatną.
Oto Gist klasy , więc możesz go rozwidlić i edytować.
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;
}
}
}
Również upewnij się, aby dodać to uprawnienie do ciebie AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
Źródła prędkości sieci obejmują Wikipedię & http://3gstore.com/page/78_what_is_evdo_mobile_broadband.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-08 09:45:30
Możesz użyć getSubtype () aby uzyskać więcej szczegółów. Zobacz slajd 9 tutaj: 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;
}
Sprawdź również odpowiedź Emila, aby dowiedzieć się więcej o tym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-25 21:59:57
Aby uzyskać bardziej precyzyjne (i przyjazne dla użytkownika) informacje o rodzaju połączenia. Możesz użyć tego kodu (pochodzącego z metody @hide w TelephonyManager.java).
Ta metoda zwraca łańcuch opisujący bieżący typ połączenia.
tj. jeden z : "WIFI" , "2G" , "3G" , "4G" , "-" (nie podłączony) lub "?"(nieznany)
Uwaga: Ten kod wymaga API 25+, ale możesz łatwo obsługiwać starsze wersje używając int zamiast const. (Patrz komentarze w kodzie).
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 "?";
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 20:05:28
@ Emil odpowiedź powyżej jest genialna.
Mały dodatek: najlepiej użyć TelephonyManager do wykrywania typów sieci. Tak więc powyższe powinno brzmieć:
/**
* 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()));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-01 11:54:21
Odpowiedź Emila Davtyana jest dobra, ale dodano typy sieci, które nie są uwzględniane w jego odpowiedzi. Tak więc, isConnectionFast(int type, int subType)
może zwracać false, kiedy powinno być prawdziwe.
Tutaj jest zmodyfikowana klasa, która używa reflection do rozliczania dodanych typów sieci w późniejszych 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();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-13 01:27:39
Możesz zrobić niestandardową metodę, aby wykonać to zadanie.
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";
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-02 10:16:13
Na dodatek do awsome odpowiedź Emila chciałbym dodać jeszcze jedną metodę, aby sprawdzić, czy rzeczywiście masz dostęp do Internetu, jak można mieć dane ustawione na off w telefonie.
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;
}
Należy pamiętać, że służy to tylko do sprawdzania, czy istnieje połączenie danych komórkowych i zwróci false, Jeśli masz podłączony Wi-Fi, ponieważ dane komórkowe są wyłączone, gdy WiFi jest podłączony.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 20:13:10
String active_network = ((ConnectivityManager)
.getSystemService(Context.CONNECTIVITY_SERVICE))
.getActiveNetworkInfo().getSubtypeName();
Powinien ci podać nazwę sieci
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 20:14:25
Możesz sprawdzić w ten sposób
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();
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-16 14:44:45
Obecnie obsługiwane są tylko urządzenia mobilne i WIFI. Spójrz i czytelny dla człowieka typ funkcji .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-10 12:20:22