最近到处在跑着找工作,难免在面试过程中遇到这样那样的问题,记得最清楚一次在面试过程中被问到,当手机处于弱网状态下,如何处理,如何监听网络信号强度变化。但是真是蒙了,回答的乱七八糟,思路一点都不明确。今天小编在这里带领大家了解下关于手机信号强度的相关几个概念。
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手机信号强度检测详细介绍,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍Android Monkey压力测试详细介绍,包括了Android Monkey压力测试详细介绍的使用技巧和注意事项,需要的朋友参考一下 Monkey 是Android SDK提供的一个命令行工具, 可以简单,方便地运行在任何版本的Android模拟器和实体设备上。 Monkey会发送伪随机的用户事件流,适合对app做压力测试 阅读目录 环境搭建 什么是Monkey Monkey 用
本文向大家介绍Android Init进程对信号的处理流程详细介绍,包括了Android Init进程对信号的处理流程详细介绍的使用技巧和注意事项,需要的朋友参考一下 Android Init进程对信号的处理流程 在Android中,当一个进程退出(exit())时,会向它的父进程发送一个SIGCHLD信号。父进程收到该信号后,会释放分配给该子进程的系统资源;并且父进程需要调用wait()或wa
本文向大家介绍PHP根据手机号判断运营商(详细介绍附代码),包括了PHP根据手机号判断运营商(详细介绍附代码)的使用技巧和注意事项,需要的朋友参考一下 道理很简单,知道手机号规则 进行正则判断就可以 移动:134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 联通:130、131、132、152、155、156、185、186 电信:133
本文向大家介绍Android中AsyncTask详细介绍,包括了Android中AsyncTask详细介绍的使用技巧和注意事项,需要的朋友参考一下 AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合。其实AsyncTask并不是那么好,甚至有些糟糕。本文我会讲AsyncTask会引起哪些问题,如何修复这些问题,并且关于AsyncTask的一些替代方案。 Async
本文向大家介绍Android广播接收机制详细介绍(附短信接收实现),包括了Android广播接收机制详细介绍(附短信接收实现)的使用技巧和注意事项,需要的朋友参考一下 Android中广播(BroadcastReceiver)的详细讲解. 1. BroadcastReceiver的注册过程: (1).广播消息发出来后,只有订阅了该广播的对象才会接收发出来的广播消息并做出相应处理。 **(2).**
本文向大家介绍Android NDK开发详细介绍,包括了Android NDK开发详细介绍的使用技巧和注意事项,需要的朋友参考一下 Android之NDK开发 一、NDK产生的背景 Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能