从 CellSignalStrengthLte 将 RSRP 转换为 RSSI

Convert RSRP to RSSI from CellSignalStrengthLte

所以我需要获取 LTE 网络的 RSSI,我知道 CellSignalStrengthLte 有获取 RSSI 的特殊方法,但它适用于 API >= 29,但我的应用程序有最小 API 共 23 个。 但是我可以获得信号强度的 RSRP 值,我看到有一些公式可以将 RSSI 转换为 RSRP 并返回,但我不知道如何在 Android.

中应用它们

所以有人有解决办法吗?这是一个小代码示例:

    val telephonyManager = requireContext().getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        telephonyManager.allCellInfo.first().let { info ->
            when (info) {
                is CellInfoLte -> {
                    val signalStrengthLte = info.cellSignalStrength as CellSignalStrengthLte
                    signalStrengthLte.rssi // requires API >= 29
                    signalStrengthLte.dbm  // returns RSRP value
                    // Needs to convert RSRP to RSSI
                }
            }
        }

最后我无法将 RSRP 转换为 RSSI,但我设法获得了近似的 RSSI 值。在查看 CellSignalStrengthLte class 的源代码后 - 我发现了一个旧的已弃用的信号强度专用字段以及将此信号转换为近似 RSSI 值的方法。

因此,为了访问此 mSignalStrength 私有 属性,我使用了反射,然后应用了源代码中的公式。

从 class 获取私有 属性 的扩展:

@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any, R> T.getPrivateProperty(name: String): R? =
    T::class
        .memberProperties
        .firstOrNull { it.name == name }
        ?.apply { isAccessible = true }
        ?.get(this) as? R

并根据问题中的代码计算近似 RSSI 值:

val signalStrength = signalStrengthLte.getPrivateProperty<CellSignalStrengthLte, Int>("mSignalStrength")
val rssiValue = (signalStrength?.times(2))?.minus(113)

再一次——这个解决方案只需要为使用 API < 29 的设备实施,因为对于较新的版本有一个变量,returns 几乎(如果不完全)相同值。