Получить уровень сигнала GSM в Android - PullRequest
5 голосов
/ 26 августа 2011

Я новичок в Android.

Как получить силу сигнала GSM в процентах (1 - 100%)?

Ответы [ 4 ]

5 голосов
/ 12 января 2017

Пользователь, который спросил, должен был предоставить дополнительную информацию или отзыв. Тем не менее ...

Вопрос совсем не тривиален: поскольку это шкала в децибелах, она не линейна и, следовательно, более мелкие изменения оказывают большее влияние при низком уровне сигнала, тогда как более крупные изменения менее важны при высоком значении. Вот почему я сожалею, что все остальные ответы будут получать неточные значения, которые не соответствуют отображаемым на телефоне.

Предполагая, что у вас уже есть объект SignalStrength (если нет, есть еще один хороший ответ, который показывает, как это сделать), в Зефире это решается методом 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, вам следует использовать функцию преобразования дБ в линейное, но я не знаю о коэффициенте усиления в сигналах GSM.

3 голосов
/ 05 июня 2015
    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);
}

}
1 голос
/ 21 июля 2016

Имейте в виду, что .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% качество. Отсюда вы должны проявить творческий подход.

0 голосов
/ 26 августа 2011

Вы гуглили это вообще? См. это , это или это . Что касается процента, я уверен, что вы, вероятно, просто должны как-то конвертировать.

...