如何确定网络类型是2G、3G 还是4G

我有一个指示器在我的应用程序显示网络类型(2G 或3G 或4G) ,但得到网络类型后,我怎么知道它应该在哪个速度类别?

我知道如何检测网络类型:

private TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
CurrentNetworkType = telephonyManager.getNetworkType();

考虑到可能的返回值:

//   public static final int NETWORK_TYPE_1xRTT
//   Since: API Level 4
//   Current network is 1xRTT
//   Constant Value: 7 (0x00000007)
//
//   public static final int NETWORK_TYPE_CDMA
//   Since: API Level 4
//   Current network is CDMA: Either IS95A or IS95B
//   Constant Value: 4 (0x00000004)
//
//   public static final int NETWORK_TYPE_EDGE
//   Since: API Level 1
//   Current network is EDGE
//   Constant Value: 2 (0x00000002)
//
//   public static final int NETWORK_TYPE_EHRPD
//   Since: API Level 11
//   Current network is eHRPD
//   Constant Value: 14 (0x0000000e)
//
//   public static final int NETWORK_TYPE_EVDO_0
//   Since: API Level 4
//   Current network is EVDO revision 0
//   Constant Value: 5 (0x00000005)
//
//   public static final int NETWORK_TYPE_EVDO_A
//   Since: API Level 4
//   Current network is EVDO revision A
//   Constant Value: 6 (0x00000006)
//
//   public static final int NETWORK_TYPE_EVDO_B
//   Since: API Level 9
//   Current network is EVDO revision B
//   Constant Value: 12 (0x0000000c)
//
//   public static final int NETWORK_TYPE_GPRS
//   Since: API Level 1
//   Current network is GPRS
//   Constant Value: 1 (0x00000001)
//
//   public static final int NETWORK_TYPE_HSDPA
//   Since: API Level 5
//   Current network is HSDPA
//   Constant Value: 8 (0x00000008)
//
//   public static final int NETWORK_TYPE_HSPA
//   Since: API Level 5
//   Current network is HSPA
//   Constant Value: 10 (0x0000000a)
//
//   public static final int NETWORK_TYPE_HSPAP
//   Since: API Level 13
//   Current network is HSPA+
//   Constant Value: 15 (0x0000000f)
//
//   public static final int NETWORK_TYPE_HSUPA
//   Since: API Level 5
//   Current network is HSUPA
//   Constant Value: 9 (0x00000009)
//
//   public static final int NETWORK_TYPE_IDEN
//   Since: API Level 8
//   Current network is iDen
//   Constant Value: 11 (0x0000000b)
//
//   public static final int NETWORK_TYPE_LTE
//   Since: API Level 11
//   Current network is LTE
//   Constant Value: 13 (0x0000000d)
//
//   public static final int NETWORK_TYPE_UMTS
//   Since: API Level 1
//   Current network is UMTS
//   Constant Value: 3 (0x00000003)
//
//   public static final int NETWORK_TYPE_UNKNOWN
//   Since: API Level 1
//   Network type is unknown
//   Constant Value: 0 (0x00000000)

我认为 LTE 是4G,但是哪一个才是真正的3G 呢? 还有什么我会考虑2G 的。

那么3G 和非3G 之间的界限在哪里呢?

更新: 我在 https://stackoverflow.com/a/8548926/949577找到了另一个相关的答案 它使用 ConnectivityManager ()获取类型和子类型,然后将子类型分类为快速或不快速。 我不知道使用 ConnectivityManager ()是否比使用 TelephonyManager ()更好,因为它们似乎都能返回网络类型。

我还发现了一个链接,可以比较 http://en.wikipedia.org/wiki/Comparison_of_wireless_data_standards的无线数据标准。

97160 次浏览

我认为你只需要硬编码你希望它们具有的等价值。快速搜索一下这些技术中的大多数应该会给你一些关于3G 还是4G 的想法(尽管从技术上来说它们都不是真正的4G)。由于 HSPA 和 HSPA + 之间似乎没有区别,所以您可能需要运行某种速度或延迟检查,并按照这种方式执行。

您可以使用 getSubtype()了解更多细节。

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

基于 Android 开发者文档和 Wikipedia 链接,我在这里给出了评论和定义网络类型。检查评论中的链接。

可以使用 getNetworkType获取 Network 类型。

        public class CommonUtils {


/**
* To get device consuming netowkr type is 2g,3g,4g
*
* @param context
* @return "2g","3g","4g" as a String based on the network type
*/
public static String getNetworkType(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:
/**
From this link https://en.wikipedia.org/wiki/Evolution-Data_Optimized ..NETWORK_TYPE_EVDO_0 & NETWORK_TYPE_EVDO_A
EV-DO is an evolution of the CDMA2000 (IS-2000) standard that supports high data rates.


Where CDMA2000 https://en.wikipedia.org/wiki/CDMA2000 .CDMA2000 is a family of 3G[1] mobile technology standards for sending voice,
data, and signaling data between mobile phones and cell sites.
*/
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:
//Log.d("Type", "3g");
//For 3g HSDPA , HSPAP(HSPA+) are main  networktype which are under 3g Network
//But from other constants also it will 3g like HSPA,HSDPA etc which are in 3g case.
//Some cases are added after  testing(real) in device with 3g enable data
//and speed also matters to decide 3g network type
//https://en.wikipedia.org/wiki/4G#Data_rate_comparison
return "3g";
case TelephonyManager.NETWORK_TYPE_LTE:
//No specification for the 4g but from wiki
//I found(LTE (Long-Term Evolution, commonly marketed as 4G LTE))
//https://en.wikipedia.org/wiki/LTE_(telecommunication)
return "4g";
default:
return "Notfound";
}
}


/**
* To check device has internet
*
* @param context
* @return boolean as per status
*/
public static boolean isNetworkConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnected();
}
}

您可以将下面的方法直接放在您的 Utilityclass 中:

科特林 :

/** Usage: `networkTypeClass(telephonyManager.networkType)` */
fun networkTypeClass(networkType: Int): String {
when (networkType) {
TelephonyManager.NETWORK_TYPE_GPRS,
TelephonyManager.NETWORK_TYPE_EDGE,
TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_1xRTT,
TelephonyManager.NETWORK_TYPE_IDEN,
TelephonyManager.NETWORK_TYPE_GSM
-> return "2G"
TelephonyManager.NETWORK_TYPE_UMTS,
TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A,
TelephonyManager.NETWORK_TYPE_HSDPA,
TelephonyManager.NETWORK_TYPE_HSUPA,
TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_EVDO_B,
TelephonyManager.NETWORK_TYPE_EHRPD,
TelephonyManager.NETWORK_TYPE_HSPAP,
TelephonyManager.NETWORK_TYPE_TD_SCDMA
-> return "3G"
TelephonyManager.NETWORK_TYPE_LTE
-> return "4G"
TelephonyManager.NETWORK_TYPE_NR
-> return "5G"
else -> return "Unknown"
}
}

Java :

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";
case TelephonyManager.NETWORK_TYPE_NR:
return "5G";
default:
return "Unknown";
}
}

感谢来自 Android 源代码的帮助。 = ]

从技术上讲,1xRTT 是一种3G 技术(尽管许多人认为它只是基于数据速度的2G)。此外,您还需要将 WiMax 添加到 switch 语句中以返回4G。它不再经常使用,但 Sprint 的 WiMax 网络目前仍在运行。

支持 Kotlin 5G的 API 29/Android Q 更新版本:

enum class Generation {
`2G`,
`3G`,
`4G`,
`5G`
}


fun getNetworkGeneration(context: Context): Generation? {
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
return when (telephonyManager.networkType) {
TelephonyManager.NETWORK_TYPE_UNKNOWN -> null


TelephonyManager.NETWORK_TYPE_GPRS,
TelephonyManager.NETWORK_TYPE_EDGE,
TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_1xRTT,
TelephonyManager.NETWORK_TYPE_IDEN,
TelephonyManager.NETWORK_TYPE_GSM -> Generation.`2G`


TelephonyManager.NETWORK_TYPE_UMTS,
TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A,
TelephonyManager.NETWORK_TYPE_HSDPA,
TelephonyManager.NETWORK_TYPE_HSUPA,
TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_EVDO_B,
TelephonyManager.NETWORK_TYPE_EHRPD,
TelephonyManager.NETWORK_TYPE_HSPAP,
TelephonyManager.NETWORK_TYPE_TD_SCDMA -> Generation.`3G`


TelephonyManager.NETWORK_TYPE_LTE,
TelephonyManager.NETWORK_TYPE_IWLAN -> Generation.`4G`


TelephonyManager.NETWORK_TYPE_NR -> Generation.`5G`


else -> null
}
}

在你的活动中这样使用它:

val generation = getNetworkGeneration(this)
when (generation) {
Generation.`2G` -> TODO()
Generation.`3G` -> TODO()
Generation.`4G` -> TODO()
Generation.`5G` -> TODO()
null -> TODO()
}