如何在安卓手机上获取LTE信号强度?

15

我正在使用Verizon的HTC Thunderbolt新LTE手持设备。在LTE网络下,我无法找到查询信号强度的API。通过进入测试模式(##4636##),我可以看到信号强度为-98dBm 2 asu。有人知道我可以使用哪个API来获取此信息吗?

4个回答

16

警告:此解决方案应适用于API17以下的Android系统。某些人可能在使用新的API或特定手机品牌(如华为)时遇到问题。

您需要使用此代码。实际上,您需要的所有信息都在这里:

String ssignal = signalStrength.toString();

String[] parts = ssignal.split(" ");
parts[]数组将包含这些元素:
part[0] = "Signalstrength:"  _ignore this, it's just the title_

parts[1] = GsmSignalStrength

parts[2] = GsmBitErrorRate

parts[3] = CdmaDbm

parts[4] = CdmaEcio

parts[5] = EvdoDbm

parts[6] = EvdoEcio

parts[7] = EvdoSnr

parts[8] = LteSignalStrength

parts[9] = LteRsrp

parts[10] = LteRsrq

parts[11] = LteRssnr

parts[12] = LteCqi

parts[13] = gsm|lte|cdma

parts[14] = _not really sure what this number is_

那么,LTEdBm是什么:

TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

int dbm = 0;

if ( tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE){

    // For Lte SignalStrength: dbm = ASU - 140.
    dbm = Integer.parseInt(parts[8])-140;

}
else{

    // For GSM Signal Strength: dbm =  (2*ASU)-113.
    if (signalStrength.getGsmSignalStrength() != 99) {
                    int intdbm = -113 + 2
                            * signalStrength.getGsmSignalStrength();
                    dbm = Integer.toString(intdbm);
                }
}

再见


3
signalStrength 的源头是什么? - CodeTower
1
我不太确定(几个月前的事了),但我认为它来自SignalStrength对象:[链接]http://developer.android.com/reference/android/telephony/SignalStrength.html#toString()。[/链接][代码] public void onSignalStrengthsChanged(SignalStrength signalStrength) { super.onSignalStrengthsChanged(signalStrength);}[/代码] - Cocorico
1
这是一个有趣的解决方案,但SignalStrength实现在所有设备上并不一致,并且并不总是按照那个顺序/带有那些值报告。 - Tom
谢谢Tom。是的,这不太一致,但这是我找到的唯一解决方案。如果我没记错,有些设备没有设置所有值。也许4G太新了...你有其他的解决方案吗? - Cocorico
1
检查所有设备,在华为手机上我遇到了一个问题,数值被移位了。 - pkuszewski
显示剩余7条评论

14
为了解决这个问题,我创建了一个名为“信号强度检测器”的应用程序,并在GitHub上提供源代码。根据我的过去经验,在运行Android ICS 4.0及以上版本的某些设备上,SignalStrength有一个getLevel方法,返回一个从0到4的整数,表示信号强度。在一些其他LTE设备上(我不认为HTC Thunderbolt是其中之一),有一些方法,如getLteCqi getLteRsrp getLteRsrqgetLteRssnr,你需要自己确定如何使用这些值来计算信号强度。最后,我发现在一些设备上(我相信HTC Thunderbolt就是其中之一),LTE信号强度实际上是用标注为GSM信号强度的方法报告出来的!这太疯狂了,但却是真实的。欢迎下载“信号强度检测器”并在您的设备上查看结果和/或根据需要修改代码。
另外,你需要使用反射来访问这些方法,如何最好地实现这一点,我将留给你自己决定。它相当简单,但你需要做很多try-catch来确定方法是否存在,并有时使用setAccessible(true)来忽略任何私有方法的问题。
希望这可以帮助到你!

大多数的链接都不是很重要。源代码仍然可以在 GitHub 上找到。最重要的是您能看到供应商如何实现 API 存在一些不一致,因此最终需要您付出一些努力来构建一个可以准确复制设备状态栏/设置界面的工具。 - Tom
1
好的,链接没问题。你的代码做的事情和我的类似,对吧? - Cocorico
这段代码只是一个使用反射查看可用API的实用工具,它不会明确地给出信号强度,但对于需要特殊处理的设备进行性能分析非常有用。我建议在遇到“问题设备”(即接收负面邮件/评论的设备)时使用它进行修复。这对于在任何公开API之前就支持LTE等技术的设备尤为重要。 - Tom
@WilliamLopes 我其实不确定,我并不声称理解任何信号相关的值,我只是提供了一种获取它们的方法,如果需要的话。 - Tom
2
@williamlopes 在LTE中,cid的最后一个字节是扇区。short_cid = long_cid / 0x100 - Tim S.
显示剩余2条评论

9
这是一个完整的工作实现示例应用程序,它使用反射来获取LTE信号强度:
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;

public class MainActivity extends Activity
{
    /*
     * Some significant methods for LTE: getLteSignalStrength, getLteRssi,
     * getLteRsrp and getRsrq. RSRP provides information about signal strength
     * and RSSI helps in determining interference and noise information. RSRQ
     * (Reference Signal Receive Quality) measurement and calculation is based
     * on both RSRP and RSSI.
     */

    private SignalStrength      signalStrength;
    private TelephonyManager    telephonyManager;
    private final static String LTE_TAG             = "LTE_Tag";
    private final static String LTE_SIGNAL_STRENGTH = "getLteSignalStrength";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        // Listener for the signal strength.
        final PhoneStateListener mListener = new PhoneStateListener()
        {
            @Override
            public void onSignalStrengthsChanged(SignalStrength sStrength)
            {
                signalStrength = sStrength;
                getLTEsignalStrength();
            }
        };

        // Register the listener for the telephony manager
        telephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    }

    private void getLTEsignalStrength()
    {
            try
            {
                Method[] methods = android.telephony.SignalStrength.class.getMethods();

                for (Method mthd : methods)
                {
                    if (mthd.getName().equals(LTE_SIGNAL_STRENGTH))
                    {
                        int LTEsignalStrength = (Integer) mthd.invoke(signalStrength, new Object[] {});
                        Log.i(LTE_TAG, "signalStrength = " + LTEsignalStrength);
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                Log.e(LTE_TAG, "Exception: " + e.toString());
            }
    }
}

你能告诉我Strength的最大和最小长度吗? - Dulaj Madusanka

-1

1
SignalStrength对象不包括从4G LTE无线电获取信息的功能,只支持CDMA、EVDO和GSM。虽然有一个隐藏的Wimax API,但我没有找到UMTS LTE的任何信息。 - Tom
你发现了哪些WiMAX的隐藏API?你有相关链接吗? - Philippe Girolami
WiMAX的隐藏API在不同的OEM之间是不一致的,因此我建议您查看上面链接到我们博客中的答案。这与SignalStrength无关,它们都在不同的类和服务中,您需要结合反射和意图来获取这些结果以形成RSSI,然后您需要计算实际含义。 - Tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接