怎么样获取信号强度
使用PhoneStateListener,更多具体信息见点击打开链接
PhoneStateListener需要实现的回调函数是
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
// default implementation empty
}
TelephonyManager启动监听PhoneStateListener时候使用LISTEN_SIGNAL_STRENGTH常量做参数
public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002;
SignalStrength相关
frameworks/base/telephony/java/android/telephony/SignalStrength.aidl
package android.telephony;
parcelable SignalStrength;
就一行,标明这个是可序列化的类,就是为了进程间传输,在binder ipc机制下要想进程间传输必须这样做。具体可见Android中Parcelable接口用法
frameworks/base/telephony/java/android/telephony/SignalStrength.java public void writeToParcel(Parcel out, int flags) {
out.writeInt(mGsmSignalStrength); //Gsm相关,2G
out.writeInt(mGsmBitErrorRate);
out.writeInt(mCdmaDbm); //cdma相关,1x
out.writeInt(mCdmaEcio);
out.writeInt(mEvdoDbm); //evdo相关,3G
out.writeInt(mEvdoEcio);
out.writeInt(mEvdoSnr);
out.writeInt(mLteSignalStrength); //lte相关,4G
out.writeInt(mLteRsrp);
out.writeInt(mLteRsrq);
out.writeInt(mLteRssnr);
out.writeInt(mLteCqi);
out.writeInt(isGsm ? 1 : 0); //标明是Gsm信号还是cdma信号
...
}
上面是实现Parcelable的方法,从中大体可以看出SignalStrength要传递的信息,下面是最常用的方法getLevel
public int getLevel() {
int level;
if (isGsm) {
level = getLteLevel();
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
level = getGsmLevel();
}
} else {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know evdo, use cdma */
level = cdmaLevel;
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* 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;
分gsm和cdma两个分支,cdma有自身特殊性,2/3G是同时在线的,所以国内手机一般显示Cdma信号会双行显示。分不同情况会调用getGsmLevel、getLteLevel、getCdmaLevel和getEvdoLevel四个方法,下面以getGsmLevel举例
public int getGsmLevel() {
int level;
int asu = getGsmSignalStrength();
...
if (asu <= 2 || asu == 99) {
level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
} else if (asu >= 12) {
level = SIGNAL_STRENGTH_GREAT;
} else if (asu >= 8) {
level = SIGNAL_STRENGTH_GOOD;
} else if (asu >= 5) {
level = SIGNAL_STRENGTH_MODERATE;
} else {
level = SIGNAL_STRENGTH_POOR;
}
...
}
依据asu值(asu具体见
信号多少才算强?dbm和asu信号单位解析)不同返回五个值,如下:
/** @hide */
public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
/** @hide */
public static final int SIGNAL_STRENGTH_POOR = 1;
/** @hide */
public static final int SIGNAL_STRENGTH_MODERATE = 2;
/** @hide */
public static final int SIGNAL_STRENGTH_GOOD = 3;
/** @hide */
public static final int SIGNAL_STRENGTH_GREAT = 4;
对应于信号格数。日常工作中唯一修改的估计就是getxxLevel中的if..else语句中的判断条件了,这个各个手机生产厂商自己定义,为了机器好卖,故意把信号格数判断条件降低之类的...真的能骗到一片人的。有的双卡机器卡2信号强度之低是硬件决定的啊,软件木办法。
不喜欢双卡机器,苹果也一直是单卡机器,不过目前为了广大中国用户苹果要破例了,iphone 8双卡双待,我想乔帮主在世绝不会让这发生的。