Android TelephonyManager 信号强度

手机网络信号强度的单位是 dBm (毫瓦分贝),一般用负数表示。

正常手机信号变化范围是从 -110dBm (差)到 -50dBm (好)之间,如果比 -50dBm 还小的话,说明你就站在基站的附近。

2G,3G,4G 获得信号强度的方式都是重写 PhoneStateListener 的 onSignalStrengthsChanged() 方法,当信号强度发生改变的时候就会触发这个事件,我们可以在这个事件里获取信号强度。

关于 dBm,还有一个定公式:

1
2
dBm = -113 + 2 * asu  #2G
dBm = -140 + asu      #4G

上面公式中的 asu 是英文 alone signal unit 的简写,是 google 为 android 设备定义的信号强度单位。,其中 dBm 是通用单位,asu 是安卓手机特有单位。

dBm 是一个表示功率绝对值的值(也可以认为是以 1mW 功率为基准的一个比值),计算公式为:10log (功率值/1mw)。

如果功率 P 为 1mw,折算为 dBm 后为 0dBm。对于 0.01mW 的功率,按 dBm 单位进行折算后的值应为:10log(0.01/1) = -20dBm。

这个数值越大,表明信号越好。由于手机信号强度一般较小,折算成为 dBm 一般都是负数。

设置-系统-关于手机-状态消息-网络 中查看信号强度 设置-系统-关于手机-状态消息-网络 中查看信号强度

另外因为笔者的卡都是移动卡,联通和电信的不知道,但是从源码里看到这样几个 API,应该可以用这些直接获取信号强度:

方法说明
getEvdoDbm()电信3G
getCdmaDbm()联通 3G
getLteDbm()4G

我们写一个 demo 来获取当前的手机的信号强度。

Demo演示界面 Demo演示界面

  1. 创建一个 空的 Android 项目 cn.twle.android.PhoneDBM.

  2. 修改 activity_main.xml.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="32dp">

    <TextView
        android:id="@+id/ms_dbm_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
  1. 修改 AndroidManifest.xml 获取手机状态改变权限。
1
2
<!-- 添加访问手机状态的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  1. 修改 MainActivity.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package cn.twle.android.phonedbm;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView ms_dbm_info;
    private TelephonyManager tm;

    private PhoneStateListener listener = new PhoneStateListener() {
        private int asu = 0,lastSignal = 0;
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            asu = signalStrength.getGsmSignalStrength();
            lastSignal = -113 + 2 * asu;
            ms_dbm_info.setText("当前手机的信号强度:" + lastSignal + " dBm" );
            super.onSignalStrengthsChanged(signalStrength);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tm = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE));

        ms_dbm_info = (TextView) findViewById(R.id.ms_dbm_info);

        tm.listen(listener, 290);
    }

}