Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve GSM signal strength in Android

I'm a newbie to Android.

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

like image 236
Ashraf Avatar asked Aug 26 '11 15:08

Ashraf


2 Answers

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.

like image 99
Yago Méndez Vidal Avatar answered Oct 09 '22 23:10

Yago Méndez Vidal


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

}
like image 3
Peter Barbanyaga Avatar answered Oct 09 '22 23:10

Peter Barbanyaga