android手机信号强度检测
Android开发之获取网络类型(WIFI、2G、3G、4G)和运营商名称
wifi 和 手机网络信号强度的获取不同要注意
android定义了2种信号单位:dBm和asu。
信号强度单位:
dBm(1毫瓦的分贝数)和asu(alone signal unit 独立信号单元)。
它们之间的关系是:dBm =-113+2asu,
这是google给android手机定义的特有信号单位。例如,我的信号强度为-53dBm,则对应30asu,因为-53 = -113 + (230) 。
这是google给android手机定义的特有信号单位。而且信号强度数值越大越好,67dbm VS -90dbm ,前者信号比后者好!
中国移动的规范规定,手机接收电平>=(城市取-90dBm;乡村取-94dBm)时,则满足覆盖要求,也就是说此处无线信号强度满足覆盖要求,即接受电平>=-90dBm,就可以满足覆盖要求
-67dBm要比-90dBm信号要强20多个dB,那么它在打电话接通成功率和通话过程中的话音质量都会好的多(当然也包括EDGE(EDGE是一种从GSM到3G的过渡技术)/GPRS上网的速度那些 )
电信
2G CDMA
3G CDMA2000
4G TD-LTE,FDD-LTE
移动
2G GSM
3G TD-SCDMA
4G TD-LTE,FDD-LTE
联通
2G GSM
3G WCDMA
4G TD-LTE,FDD-LTE
0 —— (-55)dbm 满格(4格)信号
(-55) —— (-70)dbm 3格信号
(-70) —— (-85)dbm 2格信号
(-85) —— (-100)dbm 1格信号
public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
public static final int SIGNAL_STRENGTH_POOR = 1;
public static final int SIGNAL_STRENGTH_MODERATE = 2;
public static final int SIGNAL_STRENGTH_GOOD = 3;
public static final int SIGNAL_STRENGTH_GREAT = 4;
public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
//无 ,低劣的 ,适度的 ,好 ,优异的
public static final String[] SIGNAL_STRENGTH_NAMES = {
"none", "poor", "moderate", "good", "great"
};
//SignalStrength: 0 -153824042 0 255 0 0 32767 -1 32767 -1 -72 -3 30 -1 0 -1 false gw|lte
@Override
public String toString() {
return ("SignalStrength:"
+ " " + mGsmSignalStrength
+ " " + mGsmBitErrorRate
+ " " + mCdmaDbm
+ " " + mCdmaEcio
+ " " + mEvdoDbm
+ " " + mEvdoEcio
+ " " + mEvdoSnr
+ " " + mLteSignalStrength
+ " " + mLteRsrp
+ " " + mLteRsrq
+ " " + mLteRssnr
+ " " + mLteCqi
+ " " + mTdScdmaRscp
+ " " + (isGsm ? "gsm|lte" : "cdma"));
}
//为总体信号强度检索抽象级别值: 0弱 5强
public int getLevel() {
int level = 0;
if (isGsm) {
level = getLteLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//0
level = getTdScdmaLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//0
level = getGsmLevel();
}
}
} else {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//0
/* We don't know evdo, use cdma */
level = cdmaLevel;
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//0
/* We don't know cdma, use evdo */
level = evdoLevel;
} else {
/* We know both, use the lowest level */
level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
}
}
if (DBG) log("getLevel=" + level);
return level;
}
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener MyPhoneListener = new PhoneStateListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
int level = signalStrength.getLevel();
System.out.println("level==============" + level);
int asu = signalStrength.getGsmSignalStrength();
int dbm = -113 + 2*asu;
}
};
//持续监听 onresume中
tm.listen(MyPhoneListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
//取消监听 onpause中
tm.listen(MyPhoneListener, PhoneStateListener.LISTEN_NONE);
public class NetUtils {
public static final int NETWORK_NONE = 0; // 没有网络连接
public static final int NETWORK_WIFI = 1; // wifi连接
public static final int NETWORK_2G = 2; // 2G
public static final int NETWORK_3G = 3; // 3G
public static final int NETWORK_4G = 4; // 4G
public static final int NETWORK_MOBILE = 5; // 手机流量
/**
* 获取运营商名字
*
* @param context context
* @return int
*/
public static String getOperatorName(Context context) {
/*
* getSimOperatorName()就可以直接获取到运营商的名字
* 也可以使用IMSI获取,getSimOperator(),然后根据返回值判断,例如"46000"为移动
* IMSI相关链接:http://baike.baidu.com/item/imsi
*/
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// getSimOperatorName就可以直接获取到运营商的名字
return telephonyManager.getSimOperatorName();
}
/**
* 获取当前网络连接的类型
*
* @param context context
* @return int
*/
public static int getNetworkState(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // 获取网络服务
if (null == connManager) { // 为空则认为无网络
return NETWORK_NONE;
}
// 获取网络类型,如果为空,返回无网络
NetworkInfo activeNetInfo = connManager.getActiveNetworkInfo();
if (activeNetInfo == null || !activeNetInfo.isAvailable()) {
return NETWORK_NONE;
}
// 判断是否为WIFI
NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (null != wifiInfo) {
NetworkInfo.State state = wifiInfo.getState();
if (null != state) {
if (state == NetworkInfo.State.CONNECTED || state == NetworkInfo.State.CONNECTING) {
return NETWORK_WIFI;
}
}
}
// 若不是WIFI,则去判断是2G、3G、4G网
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = telephonyManager.getNetworkType();
switch (networkType) {
/*
GPRS : 2G(2.5) General Packet Radia Service 114kbps
EDGE : 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
UMTS : 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
CDMA : 2G 电信 Code Division Multiple Access 码分多址
EVDO_0 : 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
EVDO_A : 3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
1xRTT : 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
HSDPA : 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
HSUPA : 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
HSPA : 3G (分HSDPA,HSUPA) High Speed Packet Access
IDEN : 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
EVDO_B : 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
LTE : 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G
EHRPD : 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
HSPAP : 3G HSPAP 比 HSDPA 快些
*/
// 2G网络
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return NETWORK_2G;
// 3G网络
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return NETWORK_3G;
// 4G网络
case TelephonyManager.NETWORK_TYPE_LTE:
return NETWORK_4G;
default:
return NETWORK_MOBILE;
}
}
/**
* 判断网络是否连接
*
* @param context context
* @return true/false
*/
public static boolean isNetConnected(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
/**
* 判断是否wifi连接
*
* @param context context
* @return true/false
*/
public static synchronized boolean isWifiConnected(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
int networkInfoType = networkInfo.getType();
if (networkInfoType == ConnectivityManager.TYPE_WIFI || networkInfoType == ConnectivityManager.TYPE_ETHERNET) {
return networkInfo.isConnected();
}
}
}
return false;
}
public static int getNetworkWifiLevel(Context context) {
if (!isWifiConnected(context)) {
return 0;
}
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
//获得信号强度值
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
int level = wifiInfo.getRssi();
//根据获得信号的强度发送信息
if (level <= 0 && level >= -50) {//最强
System.out.println("level==========1===========" + level);
return 1;
} else if (level < -50 && level >= -70) {//较强
System.out.println("level===========2==========" + level);
return 2;
} else if (level < -70 && level >= -80) {//较弱
System.out.println("level==========3===========" + level);
return 3;
} else if (level < -80 && level >= -100) {//微弱
System.out.println("level==========4===========" + level);
return 4;
} else {
System.out.println("level==========5===========" + level);
return 5;
}
}
return 0;
}
}
public class MainActivity extends AppCompatActivity {
public TextView mTextView;
public TelephonyManager mTelephonyManager;
public PhoneStatListener mListener;
/**
* 网络信号强度监听
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_wifi);
mTextView = (TextView) findViewById(R.id.textview);
//获取telephonyManager
mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
//开始监听
mListener = new PhoneStatListener();
//监听信号强度
mTelephonyManager.listen(mListener, PhoneStatListener.LISTEN_SIGNAL_STRENGTHS);
}
@Override
protected void onResume() {
super.onResume();
mTelephonyManager.listen(mListener, PhoneStatListener.LISTEN_SIGNAL_STRENGTHS);
}
@Override
protected void onPause() {
super.onPause();
//用户不在当前页面时,停止监听
mTelephonyManager.listen(mListener, PhoneStatListener.LISTEN_NONE);
}
@SuppressWarnings("deprecation")
private class PhoneStatListener extends PhoneStateListener {
//获取信号强度
@Override
public void onSignalStrengthChanged(int asu) {
super.onSignalStrengthChanged(asu);
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
//获取网络信号强度
//获取0-4的5种信号级别,越大信号越好,但是api23开始才能用
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
int level = signalStrength.getLevel();
System.out.println("level====" + level);
}
int cdmaDbm = signalStrength.getCdmaDbm();
int evdoDbm = signalStrength.getEvdoDbm();
System.out.println("cdmaDbm=====" + cdmaDbm);
System.out.println("evdoDbm=====" + evdoDbm);
int gsmSignalStrength = signalStrength.getGsmSignalStrength();
int dbm = -113 + 2 * gsmSignalStrength;
System.out.println("dbm===========" + dbm);
//获取网络类型
int netWorkType = NetUtils.getNetworkState(MainActivity.this);
switch (netWorkType) {
case NetUtils.NETWORK_WIFI:
mTextView.setText("当前网络为wifi,信号强度为:" + gsmSignalStrength);
break;
case NetUtils.NETWORK_2G:
mTextView.setText("当前网络为2G移动网络,信号强度为:" + gsmSignalStrength);
break;
case NetUtils.NETWORK_3G:
mTextView.setText("当前网络为3G移动网络,信号强度为:" + gsmSignalStrength);
break;
case NetUtils.NETWORK_4G:
mTextView.setText("当前网络为4G移动网络,信号强度为:" + gsmSignalStrength);
break;
case NetUtils.NETWORK_NONE:
mTextView.setText("当前没有网络,信号强度为:" + gsmSignalStrength);
break;
case -1:
mTextView.setText("当前网络错误,信号强度为:" + gsmSignalStrength);
break;
}
}
}
}