Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Signal Strength in Level, DBM, and ASU

I am currently writing an application for a client who wants to gather data regarding the signal strength at set intervals.

Currently I am using this code:

private static class MyPhoneStateListener extends PhoneStateListener
{
  @Override
  public void onSignalStrengthsChanged(SignalStrength signalStrength)
  {
     super.onSignalStrengthsChanged(signalStrength);
     telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
     InfoStore.setSignal(String.valueOf(signalStrength.getGsmSignalStrength()));
  }
};

This works fine, however the client wants the signal strength in both level (I guess how many bars?), DBM, and ASU.

Anyone have any clue how to read the signal strengths using those different forms?

like image 663
Aelexe Avatar asked Feb 20 '13 01:02

Aelexe


People also ask

What is a good dBm and ASU signal strength?

The closer you are to -50 dBm, the better your signal strength. -90 dBm or over is good and reliable.

What is good ASU for phone signal?

Signal strengths can range from approximately -30 dBm to -110 dBm. The closer that number is to 0, the stronger the cell signal. In general, anything better than -85 decibels is considered a usable signal.

What is ASU in mobile signal strength?

(ASU is a representation of the rate at which the phone is able to update its location by connecting to the towers near it.) It basically measures the same thing as dBm, but on a more linear scale. You can convert ASU to dBm with this formula: dBm= -113+(2*ASU).

What is the difference between dBm and ASU?

How do you compare signal strength with dBm and ASU unit? ASU is the arbitrary strength unit, a value expressed in integers. dBm is decibels using 1 milliwatt as the reference. ASU varies depending on the network, dBm is a channel power measurement.


2 Answers

As mentioned by Charles Ma and Kevin Krumwiede the relevant Android methods are hidden (probably for good reason), however it is still possible to get the values by reflection. Thus one solution to original question:

private class MyPhoneStateListener extends PhoneStateListener
{
    public static final int INVALID = Integer.MAX_VALUE;

    public int signalStrengthDbm = INVALID;
    public int signalStrengthAsuLevel = INVALID;

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength)
    {
        signalStrengthDbm = getSignalStrengthByName(signalStrength, "getDbm");
        signalStrengthAsuLevel = getSignalStrengthByName(signalStrength, "getAsuLevel");
    }

    private int getSignalStrengthByName(SignalStrength signalStrength, String methodName)
    {
        try
        {
            Class classFromName = Class.forName(SignalStrength.class.getName());
            java.lang.reflect.Method method = classFromName.getDeclaredMethod(methodName);
            Object object = method.invoke(signalStrength);
            return (int)object;
        }
        catch (Exception ex)
        {
            return INVALID;
        }
    }
}
like image 188
Ken Avatar answered Oct 23 '22 11:10

Ken


In android 4.x the SignalStrength class has getAsuLevel, getDbm, as well as getLevel (bars) methods.

If you need this to work for older android versions, have a look at the source code and you can copy the implementations of those methods over. http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.1.2_r1/android/telephony/SignalStrength.java/

The only thing that you can't get is the Lte measurements in older android versions, but you can probably use java reflection to see if the getLte* methods exist and call it.

like image 40
Charles Ma Avatar answered Oct 23 '22 11:10

Charles Ma