Search code examples
androidtelephonymanager

Detect 5G connection on Android phone


I'm trying to identify the type of cellular connection. I've used different methods, like for example the one suggested here, but I keep getting 4G as a result, on a Samsung with Android 10 and 5G connection. How is it possible to read the correct network type?

private fun getNetworkType(telephonyManager: TelephonyManager): String {
    return when (telephonyManager.networkType) {
        TelephonyManager.NETWORK_TYPE_UNKNOWN -> "unknown"

        TelephonyManager.NETWORK_TYPE_GPRS,
        TelephonyManager.NETWORK_TYPE_EDGE,
        TelephonyManager.NETWORK_TYPE_CDMA,
        TelephonyManager.NETWORK_TYPE_1xRTT,
        TelephonyManager.NETWORK_TYPE_IDEN,
        TelephonyManager.NETWORK_TYPE_GSM -> "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 -> "3G"

        TelephonyManager.NETWORK_TYPE_LTE,
        TelephonyManager.NETWORK_TYPE_IWLAN -> "4G"

        TelephonyManager.NETWORK_TYPE_NR -> "5G"

        else -> "something else"
    }
}

private fun getRadioTechnology(telephonyManager: TelephonyManager): String {
    try {
        val obj = Class.forName(telephonyManager.javaClass.name)
                .getDeclaredMethod("getServiceState", *arrayOfNulls(0)).invoke(telephonyManager, *arrayOfNulls(0))
        val methods: Array<Method> = Class.forName(obj.javaClass.name).declaredMethods
        for (method in methods) {
            if (method.name == "getRadioTechnology" ) {
                method.isAccessible = true
                val radioTechnology = (method.invoke(obj) as Int).toInt()
                return "$radioTechnology"
            }
        }
    } catch (e: Exception) {
        Log.e("Test5G", "", e)
    }
    return ""
}

@SuppressLint("MissingPermission")
fun getActiveSubscriptionInfoList(): String {
    val subscriptionInfos = SubscriptionManager.from(this).activeSubscriptionInfoList
    var ret: String = ""
    for(sub in subscriptionInfos) {
        val id = sub.subscriptionId
        val telephonyManager = telephonyManager.createForSubscriptionId(id);
        ret += getRadioTechnology(telephonyManager)
    }
    return ret
}

Solution

  • This is how I did it:

    telephonyManager.listen(object : PhoneStateListener() {
        override fun onServiceStateChanged(serviceState: ServiceState) {
            val isNrAvailable = serviceState.toString().isNrAvailable()
            // use isNrAvailable
        }
    }, PhoneStateListener.LISTEN_SERVICE_STATE)
    

    Where

    fun String.isNrAvailable() =
            contains("nrState=CONNECTED") ||
            contains("nsaState=5"))