Android信号强度

怎么样获取信号强度

使用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双卡双待,我想乔帮主在世绝不会让这发生的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值