欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android手机信号强度检测详细介绍

程序员文章站 2024-02-29 12:48:16
最近到处在跑着找工作,难免在面试过程中遇到这样那样的问题,记得最清楚一次在面试过程中被问到,当手机处于弱网状态下,如何处理,如何监听网络信号强度变化。但是真是蒙了,回答的乱...

最近到处在跑着找工作,难免在面试过程中遇到这样那样的问题,记得最清楚一次在面试过程中被问到,当手机处于弱网状态下,如何处理,如何监听网络信号强度变化。但是真是蒙了,回答的乱七八糟,思路一点都不明确。今天小编在这里带领大家了解下关于手机信号强度的相关几个概念。

android手机信号强度介绍

android定义了2种信号单位:dbm和asu。它们之间的关系是:dbm =-113+2asu,这是google给android手机定义的特有信号单位。例如,我的信号强度为-53dbm,则对应30asu,因为-53 = -113 + (230) 。

详细介绍两者:

asu:alone signal unit 独立信号单元,是一种模拟信号。asu仅仅代表手机将它的位置传递给附近的信号塔的速率。它和dbm测量的是一样的东西,但是是以一种更加线性的方式来表示。
dbm:是一个表示功率绝对值的值(也可以认为是以1mw功率为基准的一个比值),计算公式为:10log(功率值/1mw)。

[例] 如果功率p为1mw,折算为dbm后为0dbm。

[例] 对于0.01mw的功率,按dbm单位进行折算后的值应为: 10log(0.01/1)=-20dbm。

这个数值越大,表明信号越好。由于手机信号强度一般较小,折算成为dbm一般都是负数。
中国移动的规范规定,手机接收电平>=(城市取-90dbm;乡村取-94dbm) 时,则满足覆盖要求,

也就是说此处无线信号强度满足覆盖要求.-67dbm要比-90dbm信号要强20多个db,

那么它在打电话接通成功率和通话过程中的话音质量都会好的多。再引入一个相关概念db。

db:是一个表征相对值的值,纯粹的比值,只表示两个量的相对大小关系,没有单位,当考虑甲的功率相比于乙功率大或小多少个db时,按下面的计算公式:10log(甲功率/乙功率),如果采用两者的电压 比计算,要用20log(甲电压/乙电压)。

[例] 甲功率比乙功率大一倍,那么10lg(甲功率/乙功率)=10lg2=3db,即甲的功率比乙的功率大3 db。反之,如果甲的功率是乙的功率的一半,则甲的功率比乙的功率小3 db。

总结:dbm是负数,越接近0信号强度越高,信号越好,但不可能为0。asu为正数,值越大信号越好。db是两个量之间的比值,表示两个量间的相对大小,而dbm则是表示功率绝对大小的值。

关于对数运算,不记得的自行复习一下了。

下面再来了解一下网络类型吧,还是很多的,不过在国内只要了解国内三大运营商的网络类型大概就可以了。

电信

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

而谷歌api给我们提供的有19种类型,在telephonymanager类中定义,具体如下

/** network type is unknown */
public static final int network_type_unknown = 0;
/** current network is gprs */
public static final int network_type_gprs = 1;
/** current network is edge */
public static final int network_type_edge = 2;
/** current network is umts */
public static final int network_type_umts = 3;
/** current network is cdma: either is95a or is95b*/
public static final int network_type_cdma = 4;
/** current network is evdo revision 0*/
public static final int network_type_evdo_0 = 5;
/** current network is evdo revision a*/
public static final int network_type_evdo_a = 6;
/** current network is 1xrtt*/
public static final int network_type_1xrtt = 7;
/** current network is hsdpa */
public static final int network_type_hsdpa = 8;
/** current network is hsupa */
public static final int network_type_hsupa = 9;
/** current network is hspa */
public static final int network_type_hspa = 10;
/** current network is iden */
public static final int network_type_iden = 11;
/** current network is evdo revision b*/
public static final int network_type_evdo_b = 12;
/** current network is lte */
public static final int network_type_lte = 13;
/** current network is ehrpd */
public static final int network_type_ehrpd = 14;
/** current network is hspa+ */
public static final int network_type_hspap = 15;
/** current network is gsm {@hide} */
public static final int network_type_gsm = 16;
/** current network is td_scdma {@hide} */
public static final int network_type_td_scdma = 17;
/** current network is iwlan {@hide} */
public static final int network_type_iwlan = 18;

下面通过一些实例来测试一下吧

首先记得加权限

<uses-permission android:name="android.permission.internet"/>
<uses-permission android:name="android.permission.change_network_state"/>
<uses-permission android:name="android.permission.access_wifi_state"/>
<uses-permission android:name="android.permission.access_network_state"/>

实例代码

public class mainactivity extends appcompatactivity {
private static final int networktype_wifi = 0;
private static final int networktype_4g = 1;
private static final int networktype_2g = 2;
private static final int networktype_none = 3;
public textview mtextview;
public telephonymanager mtelephonymanager;
public phonestatlistener mlistener;
/**
* 网络信号强度监听
*
* @param savedinstancestate
*/
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
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);
}
private class phonestatlistener extends phonestatelistener {
//获取信号强度
@override
public void onsignalstrengthschanged(signalstrength signalstrength) {
super.onsignalstrengthschanged(signalstrength);
//获取网络信号强度
//获取0-4的5种信号级别,越大信号越好,但是api23开始才能用
// int level = signalstrength.getlevel();
int gsmsignalstrength = signalstrength.getgsmsignalstrength();
//获取网络类型
int networktype = getnetworktype(mainactivity.this);
switch (networktype) {
case networktype_wifi:
mtextview.settext("当前网络为wifi,信号强度为:" + gsmsignalstrength);
break;
case networktype_2g:
mtextview.settext("当前网络为2g移动网络,信号强度为:" + gsmsignalstrength);
break;
case networktype_4g:
mtextview.settext("当前网络为4g移动网络,信号强度为:" + gsmsignalstrength);
break;
case networktype_none:
mtextview.settext("当前没有网络,信号强度为:" + gsmsignalstrength);
break;
case -1:
mtextview.settext("当前网络错误,信号强度为:" + gsmsignalstrength);
break;
}
}
}
public static int getnetworktype(context context) {
int mnetworktype = -1;
connectivitymanager manager = (connectivitymanager) context.getsystemservice(context.connectivity_service);
networkinfo networkinfo = manager.getactivenetworkinfo();
if (networkinfo != null && networkinfo.isconnected()) {
string type = networkinfo.gettypename();
if (type.equalsignorecase("wifi")) {
mnetworktype = networktype_wifi;
} else if (type.equalsignorecase("mobile")) {
return isfastmobilenetwork(context) ? networktype_4g : networktype_2g;
}
} else {
mnetworktype = networktype_none;//没有网络
}
return mnetworktype;
}
/**判断网络类型*/
private static boolean isfastmobilenetwork(context context) {
telephonymanager telephonymanager = (telephonymanager)context.getsystemservice(context.telephony_service);
if (telephonymanager.getnetworktype() == telephonymanager.network_type_lte) {
//这里只简单区分两种类型网络,认为4g网络为快速,但最终还需要参考信号值
return true;
}
return false;
}
}

关于信号获取流程,这个还需深入研究,目前只在应用层简单获取了网络信号。

以上所述是小编给大家介绍的android手机信号强度检测详细介绍,希望对大家有所帮助