在Android中获取信号强度

40

我想在调用API时获取设备的信号强度。我已经搜索了所有相关的帖子,但尚未成功。

因此,我想要获得信号强度,例如

SignalStrength ss = null  ; // some initialization

int n = ss.getGsmSignalStrength();

但是在使用时,很明显我会得到空指针异常,因为我已将SignalStrength初始化为null。但我不知道如何初始化它。

另外,我不想使用PhoneStateListener,因为它只在信号变化时触发。

我正在使用以下代码获取信号强度

TelephonyManager telephonyManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
CellInfoGsm cellinfogsm = (CellInfoGsm)telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthGsm cellSignalStrengthGsm = cellinfogsm.getCellSignalStrength();
cellSignalStrengthGsm.getDbm();

但我不想使用CellSignalStrength,因为它只适用于API级别17以上,并且在级别17以下无法工作。我希望代码在API级别7+上能够正常工作。
或者是否有其他方法,可以在调用API时获取信号强度的值?

4
可能是如何在Android中获取蜂窝服务信号强度?的重复问题。 - blahdiblah
@blahdiblah:但我不想使用PhoneStateListener。我已经参考了那个链接,但那对我没有帮助。 - VIGNESH
2
你说你不想使用PhoneStateListener,因为它只在更改时触发,但正如其他问题所指出的那样,当你的应用程序启动时,它会触发。此时,你只需要关心它何时发生变化。 - blahdiblah
10个回答

30

定义变量:

TelephonyManager mTelephonyManager;
MyPhoneStateListener mPhoneStatelistener;   
int mSignalStrength = 0;

然后将这个类添加到你的代码中:

class MyPhoneStateListener extends PhoneStateListener {

     @Override
     public void onSignalStrengthsChanged(SignalStrength signalStrength) {
         super.onSignalStrengthsChanged(signalStrength);
         mSignalStrength = signalStrength.getGsmSignalStrength();
         mSignalStrength = (2 * mSignalStrength) - 113; // -> dBm           
     }
 }

并且在您的 onCreate 方法中使用:

mPhoneStatelistener = new MyPhoneStateListener();
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyManager.listen(mPhoneStatelistener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

2
请尽量遵循Java和Android代码规范... https://source.android.com/source/code-style.html - Louis CAD
@Ingo: 如果我想将 dBm 值转换为 kbps 或 mbps,我应该如何获得? - Shweta Chauhan
你想要单位是千位每秒(kbps)还是兆位每秒(mbps)?如果你指的是从服务器上下载或上传速度,你需要测量下载所需的时间除以文件大小。例如:100MB / 60s = 1.66 mbps。 - Ingo
1
@ShwetaChauhan dBm测量信号强度(即功率),而kbps / mbps是互联网速度,两者不同。 - humble_wolf
1
这个答案已经过时了。 - kc_dev

6

全局定义:

TelephonyManager telephonyManager;
myPhoneStateListener psListener;
TextView txtSignalStr;

onCreate方法:

@Override
protected void onCreate(final Bundle savedInstanceState) {
 txtSignalStr = (TextView)findViewById(R.id.signalStrength);
 psListener = new myPhoneStateListener();
 telephonyManager = (TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
 telephonyManager.listen(psListener,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}

创建myPhoneStateListener类:
public class myPhoneStateListener extends PhoneStateListener {
    public int signalStrengthValue;

    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);
        if (signalStrength.isGsm()) {
            if (signalStrength.getGsmSignalStrength() != 99)
                signalStrengthValue = signalStrength.getGsmSignalStrength() * 2 - 113;
            else
                signalStrengthValue = signalStrength.getGsmSignalStrength();
        } else {
            signalStrengthValue = signalStrength.getCdmaDbm();
        }
        txtSignalStr.setText("Signal Strength : " + signalStrengthValue);
    }
}

这个getActivity()方法是什么? - WCM

6
public class PhoneCustomStateListener extends PhoneStateListener {

    public int signalSupport = 0;

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);

        signalSupport = signalStrength.getGsmSignalStrength();
        Log.d(getClass().getCanonicalName(), "------ gsm signal --> " + signalSupport);

        if (signalSupport > 30) {
            Log.d(getClass().getCanonicalName(), "Signal GSM : Good");


        } else if (signalSupport > 20 && signalSupport < 30) {
            Log.d(getClass().getCanonicalName(), "Signal GSM : Avarage");


        } else if (signalSupport < 20 && signalSupport > 3) {
            Log.d(getClass().getCanonicalName(), "Signal GSM : Weak");


        } else if (signalSupport < 3) {
            Log.d(getClass().getCanonicalName(), "Signal GSM : Very weak");


        }
    }
}

4
我们不应该初始化signalstrength,而是使用phonelistener并覆盖onSignalStrengthsChanged(SignalStrength signalStrength)方法。例如,看以下代码片段。
class SamplePhoneStateListener extends PhoneStateListener {

        int signalStrength = 0;

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            signalStrength = signalStrength.getGsmSignalStrength();
            //You can check the signal strength value here..
        }

    }

使用TelephonyManager对象,您可以像下面这样监听上述类:
TelephonyManagerObject.listen(myListener,
            PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)

2
这对我有用:
需要哪些服务:
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

如何收集指标:

public void startGatherMetrics() {
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    if (networkInfo != null) {
        networkInfoStr = connectivityManager.getActiveNetworkInfo().toString();

        // gather Network Capabilities
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            Network network = connectivityManager.getActiveNetwork();
            networkInfoStr += "; " + connectivityManager.getNetworkCapabilities(network).toString();
        }
    }
    Log.d("A_NETWORK_INFO", networkInfoStr);

    new Thread(new Runnable() {
        @Override
        public void run() {
            quitLooper = false;
            Looper.prepare();
            telephonyManager.listen(new PhoneStateListener() {
                @Override
                public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                    super.onSignalStrengthsChanged(signalStrength);
                    Log.d("A_NETWORK_METRICS",
                        "Signal Strength (0-4 / dBm):" + getLevel(signalStrength) + " / "
                            + getDbm(signalStrength));

                    if (quitLooper)
                        Looper.myLooper().quit();
                }
            }, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

            Looper.loop();
        }
    }).start();

}

public void stop() {
    quitLooper = true;
}

可以在这里找到"getLevel(signalStrength)"和"getDbm(signalStrength)"。


1

0
public class myPhoneStateListener extends PhoneStateListener {
    public int signalStrengthValue;

    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);
        if (signalStrength.isGsm()) {
            if (signalStrength.getGsmSignalStrength() != 99)
                signalStrengthValue = signalStrength.getGsmSignalStrength() * 2 - 113;
            else
                signalStrengthValue = signalStrength.getGsmSignalStrength();
        } else {
            signalStrengthValue = signalStrength.getCdmaDbm();
        }
        txtSignalStr.setText("Signal Strength : " + signalStrengthValue);
    }
}

访问信号强度需要精确定位权限吗? - Karthikeyan Ve

0

Kotlin 版本 :

class myPhoneStateListener : PhoneStateListener() {
    var signalStrengthValue = 0
    override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
        super.onSignalStrengthsChanged(signalStrength)
        signalStrengthValue = if (signalStrength.isGsm) {
            if (signalStrength.gsmSignalStrength != 99) signalStrength.gsmSignalStrength * 2 - 113 else signalStrength.gsmSignalStrength
        } else {
            signalStrength.cdmaDbm
        }
        txtSignalStr.setText("Signal Strength : $signalStrengthValue")
    }
}

PhoneStateListener已过时。 - Yasiru Nayanajith

0

PhoneStateListener对象应该在looper线程中实例化。因此,如果您正在使用工作线程(非GUI线程),可以使用以下内容:

private HandlerThread handlerThreadCellularSignal = null;

public void startListen() {     
        handlerThreadCellularSignal = new HandlerThread("CELLULAR_INFO_THREAD");
        handlerThreadCellularSignal.start();
        Looper looper = handlerThreadCellularSignal.getLooper();
        Handler handler = new Handler(looper);
        handler.post(new Runnable() {
            @Override
            public void run() {
                phoneStatelistener = new PhoneStateListenerEx();
                TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
                telephonyManager.listen(phoneStatelistener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
            }
        });
}

private void stopListen() {
    handlerThreadCellularSignal.quit();
}


public class PhoneStateListenerEx extends PhoneStateListener {

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        super.onSignalStrengthsChanged(signalStrength);
        int signalStrengthdBm = (2 * signalStrength.getGsmSignalStrength()) - 113; // -> dBm
        Log.d("Cellular Signal Strength | " + String.valueOf(signalStrengthdBm));
    }
}

0
PhoneStateListener已经过时,我们可以使用telephony Manager来替代。 要获取信号强度,可以使用以下代码。 还需要获取精确位置权限。
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        val cellInfoList = telephonyManager.allCellInfo
        if (cellInfoList != null) {
            for (cellInfo in cellInfoList) {
                when (cellInfo) {
                    is CellInfoGsm -> {
                        val cellSignalStrengthGsm = cellInfo.cellSignalStrength
                        val signalStrengthDbm = cellSignalStrengthGsm.dbm
                        Log.i("SignalStrength1","mobileSignalStrength${signalStrengthDbm}")
                        // Do something with signalStrengthDbm for GSM network
                    }
                    is CellInfoLte -> {
                        val cellSignalStrengthLte = cellInfo.cellSignalStrength
                        val signalStrengthDbm = cellSignalStrengthLte.dbm
                        Log.i("SignalStrength2","mobileSignalStrength${signalStrengthDbm}")
                        // Do something with signalStrengthDbm for LTE network
                    }
                    // Handle other cell info types if necessary (e.g., CellInfoWcdma, CellInfoCdma)
                }
            }
        } else {
            // No cell info available
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接