So bestimmen Sie, ob der Netzwerktyp 2G, 3G oder 4G ist


68

Ich habe eine Anzeige in meiner Anwendung, um den Netzwerktyp (2G oder 3G oder 4G) anzuzeigen. Woher weiß ich nach Erhalt des Netzwerktyps, in welcher Geschwindigkeitskategorie er sich befinden soll?

Ich weiß, wie man den Netzwerktyp erkennt:

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

Angesichts der möglichen Rückgabewerte:

//   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)

Ich würde LTE als 4G betrachten, aber welche davon werden wirklich als 3G angesehen? Alles andere würde ich als 2G betrachten.

Wo ziehen Sie die Grenze zwischen 3G oder nicht 3G?

Update: Ich habe eine weitere relevante Antwort unter https://stackoverflow.com/a/8548926/949577 gefunden Es verwendet ConnectivityManager (), um Typ und Subtyp abzurufen, und klassifiziert den Subtyp dann als schnell oder nicht. Ich weiß nicht, ob die Verwendung von ConnectivityManager () ein besserer Ansatz ist als die Verwendung von TelephonyManager (), da beide den Netzwerktyp zurückgeben können.

Außerdem habe ich unter http://en.wikipedia.org/wiki/Comparison_of_wireless_data_standards einen Link gefunden, der die Standards für drahtlose Daten vergleicht .


Antworten:


111

Sie können diese folgende Methode direkt in Ihre Utility-Klasse einfügen:

Kotlin :

/** 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";
    }
}

Dank der Unterstützung durch den Android-Quellcode. =]


2
Kannst du mir helfen, wie man diesen Code in Dual Sim Enable Mobile verwendet?
Harikrishnan

78

Basierend auf dem Android Developer-Dokument und dem Wikipedia-Link hier habe ich Kommentare abgegeben und den Netzwerktyp definiert. Überprüfen Sie die Links im Kommentar.

Sie können verwenden getNetworkType, um den Netzwerktyp abzurufen.

        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
Wenn ich mit WLAN verbunden bin, wenn ich dies ausführe, bekomme ich GPRS. Können Sie das beheben?
Skyshine

@ user1140237: Für meine Anwendung benötige ich eine ständige Internetverbindung, für die ich einen Dienst verwende, um festzustellen, ob das Internet eingeschaltet ist oder nicht, wenn nicht, dann schalte ich das Internet ein. Manchmal stehe ich vor einer Situation, in der die Datenverbindung gewesen wäre lange zurück eingeschaltet, aber aufgrund eines Problems fehlt das Internet-Symbol (H, E usw.), dh über dem Signalstärkesymbol (in der Benachrichtigung). In diesem Kontext wird das Internet wie auf ABER das Internet-Symbol angezeigt abwesend, wenn ich Ihr obiges Snippet verwende, kann es dann erkennen, ob das Symbol vorhanden ist oder nicht?
Basher51

@ Basher51 Um zu überprüfen, ob das Gerät über eine Internetverbindung verfügt oder nicht, können Sie CONNECTIVITY_ACTION developer.android.com/reference/android/net/… ... verwenden. Dort können Sie überprüfen, ob das Internet verbunden ist, wenn es sich um 2 g / 3 g handelt. Ich hoffe, ich habe Ihr Problem verstanden ... Wenn Sie mehr möchten, stellen Sie eine separate Frage für das Problem.
user1140237

Mein Telefon hat 3G, aber diese Methode gibt mir das Ergebnis NETWORK_TYPE_HSPAP, was eine falsche Erkennung ist. Die Antwort von @ Anonsage ist möglicherweise korrekter.
Changbenny

Ist es teuer, vor jeder Netzwerkanforderung anzurufen? Ich möchte einen Reftofit-Interceptor erstellen und Informationen zum Netzwerk (in Headern) an den Webdienst senden.
Vlado Pandžić

9

Sie können getSubtype()für weitere Details verwenden.

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
Es wäre toll zu wissen, welchen Typ "info" hat;) ConnectivityManager cm = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE); NetworkInfo info = cm.getActiveNetworkInfo ();
Maik Peschutter

3

Technisch gesehen ist 1xRTT eine 3G-Technologie (obwohl viele davon ausgehen, dass 2G ausschließlich auf der Datengeschwindigkeit basiert). Außerdem möchten Sie Ihrer switch-Anweisung WiMax hinzufügen, um 4G zurückzugeben. Es wird nicht mehr oft verwendet, aber das WiMax-Netzwerk von Sprint ist vorerst noch betriebsbereit.


1
Reg. 1xRTT, woher haben diese Informationen? Bitte geben Sie einen Link an. Meinen Sie auch IWLAN für WiMax?
not2qubit

3

Aktualisierte Version für API 29 / Android Q mit 5G- Unterstützung in Kotlin:

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

Verwenden Sie es so in Ihrer Aktivität:

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

1

Ich denke wirklich, Sie müssen nur den entsprechenden Wert fest codieren, den sie haben sollen. Ein schnelles Googeln der meisten dieser Technologien sollte Ihnen eine Vorstellung davon geben, welche als 3G oder 4G betrachtet wird (obwohl technisch gesehen keine von ihnen echte 4G sind). Da es keinen Unterschied zwischen HSPA und HSPA + zu geben scheint, möchten Sie möglicherweise eine Geschwindigkeits- oder Latenzprüfung durchführen und so vorgehen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.