5

我是安卓新手。

如何以百分比(1 - 100%)的形式获得 GSM 信号强度?

4

4 回答 4

6

询问的用户应该提供了更多信息或反馈。那就是说...

这个问题根本不是微不足道的:因为它是以分贝为单位的尺度,它不是线性的,因此当信号低时,较小的变化会产生更大的影响,而当值高时,较大的变化就不那么重要了。这就是为什么我很遗憾地说所有其他答案都会得到不准确的值,与手机上显示的值不匹配。

假设您已经有一个SignalStrength对象(如果没有,还有另一个很好的答案可以说明如何做到这一点),在 Marshmallow 中,它通过getGsmLevel()返回线性化比例 0-4 的方法(还有所有其他信号的方法,甚至组合)来解决. 您可以从类中查看源代码SignalStrength

/**
 * Get gsm as level 0..4
 *
 * @hide
 */
public int getGsmLevel() {
    int level;
    // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
    // asu = 0 (-113dB or less) is very weak
    // signal, its better to show 0 bars to the user in such cases.
    // asu = 99 is a special case, where the signal strength is unknown.
    int asu = getGsmSignalStrength();
    if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
    else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
    else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
    else level = SIGNAL_STRENGTH_POOR;
    if (DBG) log("getGsmLevel=" + level);
    return level;
}

拥有 0-100% 的比例没有意义,因为它对于这个问题的粒度很小,这就是为什么它更常用 0-4 范围并且在这种方法中它已经线性化。如果不在 Marshmallow 中,只需调整此方法以接收对象作为值。如果出于某种原因您真的需要 0-100 范围,您应该使用 dB 到线性转换功能,但我不知道 GSM 信号中的增益因子。

于 2017-01-11T23:17:31.333 回答
3
    public class MyActivity extends Activity {
    public static final int UNKNOW_CODE = 99;
    int MAX_SIGNAL_DBM_VALUE = 31;

    TelephonyManager tel;
MyPhoneStateListener myPhoneStateListener;

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    View view = getLayoutInflater().inflate(R.layout.activity_about, null);
    setContentView(view);

    myPhoneStateListener = new MyPhoneStateListener();
    tel = (TelephonyManager) PpsApplication.getAppContext().getSystemService(Context.TELEPHONY_SERVICE);
    tel.listen(myPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}

private class MyPhoneStateListener extends PhoneStateListener {
    /* Get the Signal strength from the provider, each tiome there is an update */
    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);

        if (null != signalStrength && signalStrength.getGsmSignalStrength() != UNKNOW_CODE) {
            int signalStrengthPercent = calculateSignalStrengthInPercent(signalStrength.getGsmSignalStrength());
            viewModel.setSignalStrengthString(IntegerHelper.getString(signalStrengthPercent));
        }
    }
}

private int calculateSignalStrengthInPercent(int signalStrength) {
    return (int) ((float) signalStrength / MAX_SIGNAL_DBM_VALUE * 100);
}

}
于 2015-06-05T06:24:30.550 回答
2

请注意 .getGsmSignalStrength(); 现在只返回酒吧:0-5,99

现在隐藏了实际值。您仍然可以使用反射来找到它们:

                int strength=signalStrength.getGsmSignalStrength();//number of bars not ASU
                Log.v("Mobile","BARS: "+strength);
                try{//Actual signal strength is hidden
                    Class classFromName = Class.forName(SignalStrength.class.getName());
                    java.lang.reflect.Method method = classFromName.getDeclaredMethod("getAsuLevel");//getDbm
                    strength = (int) method.invoke(signalStrength);
                }catch (Exception ex){Log.v("Mobile","cant retreive");}
                if (strength == 99 ) { Log.v("Mobile", "ERROR!  GSM signal strength not available!");return;}//99 = Unknown
                if (strength == 255) { Log.v("Mobile", "ERROR!  UMTS signal strength not available!");return;}//255 = Unknown

上面的示例仅适用于 ASU,它似乎比 Dbm 工作得更好。获得 ASU 值后,您可以将其转储为百分比:

                Log.v("Mobile","ASU: "+strength);
                //Data.mobile_signal=strength*20;//Number of bars 0-5
                //Data.mobile_signal = 100-((strength-113)/62);//GSM DBM
                Data.mobile_signal =(int)((double)strength*100/31);//GSM ASU
                Data.mobile_signal =(int)((double)strength*100/91);//UMTS ASU
               Log.v("Mobile","Set GSM signal from "+strength+" to "+Data.mobile_signal);

提醒一下,这适用于您有 GSM 信号而不是 CDMA 信号的情况。使用 TelephonyManager.getPhoneType(); 确定哪个:1=GSM,2=CDMA,3=SIP

可是等等!这表示我只有 50% 的信号强度,但我有 5 个条!这是错误的!

嗯,不完全是。除非您的手机就在发射器的前面,否则它可能不会 100%。但是 50% 的信号大约是 100% 的质量。所以从这里你必须发挥创造力。

于 2016-07-21T17:47:23.337 回答
0

更好的解决方案是使用:

signalStrength.level

这将返回一个 0 到 4 的值,您应该在您的 android 设备上熟悉该值。将其视为信号条的数量。这在 GSM 和 CDMA 之间是兼容的。

于 2021-05-31T14:12:24.583 回答