0 在Android中对移动数据操作的几个类和接口如下:
1 TelephonyManager 类 主要提供了一系列用于访问与手机通讯相关的状态和信息的get方法。其中包括手机SIM的状态和信息、电信网络的状态及手机用户的信息,在应用程序中可以使用这些get方法获取相关数据
TelephonyManager类的对象可以通过Context.getSystemService(Context.TELEPHONY_SERVICE)方法来获得,需要注意的是有些通讯信息的获取对应用程序的权限有一定的限制,在开发的时候需要为其添加相应的权限。
2 PhoneStateListener类方法: (移动数据强度和类型 在打电话、SIM卡插拔、连接状态等状态改变而受影响,因此需要在状态下分别检测数据强度和类型 监听回调)
1.onDataActivity(intdirection) :activity 数据状态改变时监听回调
2.onServiceStateChanged(ServiceState serviceState) {//设备服务状态改变监听回调
3.onSignalStrengthsChanged(SignalStrength signalStrength) {//信号强度改变监听回调
4.onDataConnectionStateChanged(intstate) {//数据连接状态
5.onCallStateChanged(intstate, String incomingNumber) {//电话状态改变
当信号强度发生变化时,打印log如下
1 SystemUI对于信号强度的客制化
MobileSignalController 对于信号强度的监听:
class MobilePhoneStateListener extends PhoneStateListener {
public MobilePhoneStateListener(int subId, Looper looper) {
super(subId, looper);
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
if (DEBUG) {
Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
}
mSignalStrength = signalStrength;
updateTelephony();
}
.....................................
}
/**
* Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
* mDataState, and mSimState. It should be called any time one of these is updated.
* This will call listeners if necessary.
*/
private final void updateTelephony() {
if (DEBUG && FeatureOptions.LOG_ENABLE) {
Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()
+ " ss=" + mSignalStrength);
}
mCurrentState.connected = hasService() && mSignalStrength != null;
handleIWLANNetwork();
if (mCurrentState.connected) { //如果有SIM卡信号
获取信号强度
if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
mCurrentState.level = mSignalStrength.getCdmaLevel();
} else {
mCurrentState.level = mSignalStrength.getLevel();
}
/// M: Customize the signal strength level. @ {
mCurrentState.level = mStatusBarExt.getCustomizeSignalStrengthLevel(
mCurrentState.level, mSignalStrength, mServiceState);
/// @ }
}
if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
} else {
mCurrentState.iconGroup = mDefaultIcons;
}
/// M: Add for data network type.
mCurrentState.dataNetType = mDataNetType;
mCurrentState.dataConnected = mCurrentState.connected
&& mDataState == TelephonyManager.DATA_CONNECTED;
/// M: Add for op network tower type.
mCurrentState.customizedState = mStatusBarExt.getCustomizeCsState(mServiceState,
mCurrentState.customizedState);
/// M: Add for op signal strength tower icon.
mCurrentState.customizedSignalStrengthIcon = mStatusBarExt.getCustomizeSignalStrengthIcon(
mSubscriptionInfo.getSubscriptionId(),
mCurrentState.customizedSignalStrengthIcon,
mSignalStrength,
mDataNetType,
mServiceState);
mCurrentState.roaming = isRoaming();
if (isCarrierNetworkChangeActive()) {
mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
} else if (isDataDisabled()) {
mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
}
if (isEmergencyOnly() != mCurrentState.isEmergency) {
mCurrentState.isEmergency = isEmergencyOnly();
mNetworkController.recalculateEmergency();
}
// Fill in the network name if we think we have it.
if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
&& !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
}
/// M: For network type big icon.
mCurrentState.networkIcon =
NetworkTypeUtils.getNetworkTypeIcon(mServiceState, mConfig, hasService());
/// M: For volte type icon.
mCurrentState.volteIcon = getVolteIcon();
notifyListenersIfNecessary(); //状态栏或下拉状态栏信号格显示
}
针对于信号强度,经过一系列的调用到
vendor/mediatek/proprietary/frameworks/opt/telephony-base/java/mediatek/telephony/MtkSignalStrength.java
@Override
public int getLevel() {
return super.getLevel();
}
frameworks/base/telephony/java/android/telephony/SignalStrength.java
public int getLevel() {
int level = 0;
if (isGsm) { //移动或联通卡
level = getLteLevel(); //首先获取4G信号格
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { //未获取到
level = getTdScdmaLevel(); //获取移动或联通的3G信号格
if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {//仍然未获取
level = getGsmLevel(); //获取移动或联通的2G信号格
}
}
} else {//电信
int cdmaLevel = getCdmaLevel(); //获取电信2G信号格
int evdoLevel = getEvdoLevel(); //获取电信3G信号格
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是移动和联通公用的band;LTE从编码方式上分为TDD和FDD,从频段上分有各种不同的band
移动:GSM、TDSCDMA、LTE(TDD)
联通:GSM、WCDMA、LTE(FDD)
电信:CDMA、EVDO、LTE(FDD)
因此如果手机支持GSM、WCDMA、TDSCDMA、TDD-LTE、FDD-LTE 这是五模;加上 CDMA、EVDO 就是七模
对于移动和联通,是先获取4G信号;在MtkSignalStrength中:
/**
* Get LTE as level 0..4
*
* @hide
*/
@Override
public int getLteLevel() {
int rsrpIconLevel = -1;
ISignalStrengthExt ssExt = getOpInstance(); //获取ISignalStrengthExt实例
if (ssExt != null) {
rsrpIconLevel = ssExt.mapLteSignalLevel(mLteRsrp, mLteRssnr, mLteSignalStrength);
return rsrpIconLevel;
} else {
log("[getLteLevel] null op customization instance");
}
return super.getLteLevel(); //如果上述获取不到信号格。则调用父类SignalStrength的getLteLevel方法
}
vendor/mediatek/proprietary/frameworks/opt/telephony-base/java/mediatek/telephony/SignalStrengthExt.java
public int mapLteSignalLevel(int mLteRsrp, int mLteRssnr, int mLteSignalStrength) {
/*
* TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
* signal + noise RSRP = reference signal dBm RSRQ = quality of signal
* dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
* = -10log P1/P2 dB
*/
int rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
int rsrpIconLevel = -1;
int snrIconLevel = -1;
if (mLteRsrp > -44) {
rsrpIconLevel = -1;
} else if (mLteRsrp >= -85) {
rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT; //4格
} else if (mLteRsrp >= -95) {
rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD; //3格
} else if (mLteRsrp >= -105) {
rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE; //2格
} else if (mLteRsrp >= -115) {
rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR; //1格
} else if (mLteRsrp >= -140) { //0格
rsrpIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/*
* Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
* dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
* -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
* Icon Only
*/
if (mLteRssnr > 300) {
snrIconLevel = -1;
} else if (mLteRssnr >= 130) {
snrIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;
} else if (mLteRssnr >= 45) {
snrIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;
} else if (mLteRssnr >= 10) {
snrIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;
} else if (mLteRssnr >= -30) {
snrIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;
} else if (mLteRssnr >= -200) {
snrIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
Rlog.i(TAG, "getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
+ rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
/* Choose a measurement type to use for notification */
if (snrIconLevel != -1 && rsrpIconLevel != -1) {
/*
* The number of bars displayed shall be the smaller of the bars
* associated with LTE RSRP and the bars associated with the LTE
* RS_SNR
*/
return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
}
if (snrIconLevel != -1) {
return snrIconLevel;
}
if (rsrpIconLevel != -1) {
return rsrpIconLevel;
}
/* Valid values are (0-63, 99) as defined in TS 36.331 */
if (mLteSignalStrength > 63) {
rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
} else if (mLteSignalStrength >= 12) {
rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_GREAT;
} else if (mLteSignalStrength >= 8) {
rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_GOOD;
} else if (mLteSignalStrength >= 5) {
rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE;
} else if (mLteSignalStrength >= 0) {
rssiIconLevel = SignalStrength.SIGNAL_STRENGTH_POOR;
}
Rlog.i(TAG, "getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
+ rssiIconLevel);
return rssiIconLevel;
}
因此如果想修改强度对应的信号格显示,请修改上述对应强度值;对于上述变量的介绍请参考博客关于LTE RSRP、RSSI、SINR、RSRQ定义:
2 状态栏或下拉状态栏信号格显示
MobileSignalController
public void notifyListenersIfNecessary() {
if (isDirty()) {
saveLastState();
notifyListeners();
}
}
public final void notifyListeners() {
notifyListeners(mCallbackHandler);
}
因此调用到SignalClusterView
@Override
public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int networkType, int volteIcon, int qsType, boolean activityIn, boolean activityOut,
String typeContentDescription, String description, boolean isWide, int subId,
boolean roaming) {
PhoneState state = getState(subId);
if (state == null) {
return;
}
state.mMobileVisible = statusIcon.visible && !mBlockMobile;
state.mMobileStrengthId = statusIcon.icon;
state.mMobileTypeId = statusType;
state.mMobileDescription = statusIcon.contentDescription;
state.mMobileTypeDescription = typeContentDescription;
state.mIsMobileTypeIconWide = statusType != 0 && isWide;
/// M: for big network icon and volte icon.
state.mNetworkIcon = networkType;
state.mVolteIcon = volteIcon;
state.mRoaming = roaming;
state.mActivityIn = activityIn && mActivityEnabled;
state.mActivityOut = activityOut && mActivityEnabled;
/// M: Add for plugin features. @ {
state.mDataActivityIn = activityIn;
state.mDataActivityOut = activityOut;
/// @ }
apply();
}
public boolean apply(boolean isSecondaryIcon) { //信号格显示到状态栏
if (mMobileVisible && !mIsAirplaneMode) {
if (mLastMobileStrengthId != mMobileStrengthId) {
mMobile.getDrawable().setLevel(mMobileStrengthId);
mMobileDark.getDrawable().setLevel(mMobileStrengthId);
mLastMobileStrengthId = mMobileStrengthId;
}
if (mLastMobileTypeId != mMobileTypeId) {
if (!mPhoneStateExt.disableHostFunction()) {
mMobileType.setImageResource(mMobileTypeId);
}
mLastMobileTypeId = mMobileTypeId;
}
mMobileGroup.setContentDescription(mMobileTypeDescription
+ " " + mMobileDescription);
mMobileGroup.setVisibility(View.VISIBLE);
showViewInWfcCase();
} else {
if (mIsAirplaneMode && (mIsWfcEnable && mVolteIcon != 0)) {
/// M:Bug fix for show vowifi icon in flight mode
mMobileGroup.setVisibility(View.VISIBLE);
hideViewInWfcCase();
} else {
if (DEBUG) {
Log.d(TAG, "setVisibility as GONE, this = " + this
+ ", mMobileVisible = " + mMobileVisible
+ ", mIsAirplaneMode = " + mIsAirplaneMode
+ ", mIsWfcEnable = " + mIsWfcEnable
+ ", mVolteIcon = " + mVolteIcon);
}
mMobileGroup.setVisibility(View.GONE);
}
}
..............................................
return mMobileVisible;
}