Retrieve GSM signal strength in Android
Asked Answered
A

4

5

I'm a newbie to Android.

How do I get the GSM signal Strength in terms of percentage (1 - 100%)?

Azucenaazure answered 26/8, 2011 at 15:35 Comment(2)
have you gone here firstdroid.com/2010/05/12/get-provider-gsm-signal-strengthGrandee
if that is what you searching for please search before askingGrandee
L
6

The user who asked should have provided more information or feedback. That said...

The question is not trivial at all: since it's a scale in decibels it's not linear and thus smaller changes have a greater impact when the signal is low, while bigger changes are less important when the value is high. That's why I'm sorry to say that all the other answers will be getting inaccurate values that would not match the one displayed on the phone.

Assuming you already have a SignalStrength object (if not, there's another nice answer that shows how to do it), in Marshmallow it's solved with the method getGsmLevel() (there are also methods for all other signals and even combined) that returns a linearized scale 0-4. You can check the source code from the class 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;
}

Having a 0-100% scale it's not significative because it's a small granularity for this matter, that's why it's more commonly used a 0-4 range and in this method it's already linearized. If not in Marshmallow, just adapt this method to receive the object as a value. If you'd really need a 0-100 range for some reason you should use a dB to linear conversion function, but I'm unaware of the gain factor in GSM signals.

Ling answered 11/1, 2017 at 23:17 Comment(2)
getGsmLevel works only for specific versions. Any generic solution ?Jamajamaal
Yeah, of course: just get the code for getGsmLevel() and adapt it as a static method that takes a SignalStrength object as a parameter and use it for getting the asu value calling getGsmSignalStrength() which is in all versions.Spurtle
D
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);
}

}
Dominickdominie answered 5/6, 2015 at 6:24 Comment(1)
can i get the gsm level status like 1/4 ? i need a solution for 4.x - 7.x.Jamajamaal
C
2

Be aware that .getGsmSignalStrength(); now only returns bars: 0-5,99

The actual values are now hidden. You can still get to them using reflection:

                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

The above example is for ASU only, which seems to work better than Dbm. After you get the ASU value, you can then dump it into percentage:

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

As a reminder, this is for when you have a GSM signal not a CDMA signal. Use TelephonyManager.getPhoneType(); to determine which: 1=GSM, 2=CDMA, 3=SIP

BUT WAIT! This says I only have a 50% signal strength yet I have 5 bars! This is wrong!

Well, not exactly. Unless your phone is right in front of the transmitter, it's probably not going to be 100%. But 50% signal is about 100% quality. So from here you have to get creative.

Carbine answered 21/7, 2016 at 17:47 Comment(2)
It actually returns values 0-31,99. From here. Btw, do you have any idea of why it returns 99 in most cases?Coercive
Not for LTE UMTS signals, it will give you 0-91,255. This confused me too when I first encountered it. Here I was expecting a maximum of 31 and yet I was receiving a value of 47! 99 or 255 means there is no data available.Carbine
A
0

A better solution is to use:

signalStrength.level

This returns a 0 to 4 value that you should be familiar with from your android device. Think of it as the number of bars of signal. This is compatible across GSM and CDMA.

Anselmi answered 31/5, 2021 at 14:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.