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


68

我的应用程序上有一个指示器来显示网络类型(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找到了一个比较无线数据标准的链接。


Answers:


111

您可以将以下方法直接放在Utility类中:

科特林

/** 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源代码的帮助。=]


2
您能帮我吗,如何在Dual sim enable mobile中使用此代码?
harikrishnan

78

根据此处的Android开发人员文档和Wikipedia链接,我给出了评论并定义了网络类型。请检查评论中的链接。

您可以使用getNetworkType获取网络类型。

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

1
如果我连接到wifi,如果我运行它,我会得到gprs您能解决吗
skyshine 2013年

@ user1140237:对于我的应用程序,我需要持续的互联网连接,为此我正在使用一种服务来检测互联网是否打开,如果不打开,则需要打开互联网。有时我会遇到数据连接本来是长时间打开,但由于某些问题,互联网信号(H,E等)(即在信号强度符号上(在通知中)显示)不存在。在这种情况下,互联网显示为但在互联网上显示为如果没有,如果我使用上面的代码段,它可以检测符号是否存在吗?
Basher51

@ Basher51检查设备有互联网连接,或者不是你可以使用CONNECTIVITY_ACTION developer.android.com/reference/android/net/... ......还有,你可以检查网络连接THN是2G / 3G?希望我HVE了解乌尔问题......如果想要更多的问另外一个问题了THT问题..
user1140237

我的手机有3G,但是这种方法给我的结果是NETWORK_TYPE_HSPAP,这是错误的检测。@Anonsage的答案可能更正确。
changbenny

在每个网络请求之前打电话很贵吗?我想制作reftofit拦截器并将有关网络的信息发送到Web服务(在标题中)?
弗拉多·潘兹奇(VladoPandžić),2016年

9

您可以使用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;
}

1
知道“信息”具有哪种类型将非常好;)ConnectivityManager cm =(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo();
Maik Peschutter '16

3

从技术上讲1xRTT是3G技术(尽管许多人仅基于数据速度将其视为2G)。另外,您将希望将WiMax添加到switch语句中以返回4G。它不再经常使用,但Sprint的WiMax网络暂时仍在运行。


1
Reg。1xRTT,从哪里获得该信息?请提供一个链接。您还说IWLAN for WiMax吗?
not2qubit

3

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()
}

1

我认为您实际上只需要硬编码您希望它们具有的等效值即可。快速浏览这些技术中的大多数,应该会给您一些想法,让您了解哪种技术被视为3G或4G(尽管从技术上讲,它们都不是真正的4G)。由于HSPA和HSPA +之间似乎没有区别,因此您可能需要运行某种速度或延迟检查,然后以这种方式进行检查。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.