现在android N之后很多手机都支持VOLTE了,而android手机的VOLTE是独立于其他的网络的,但是对于VOLTE打开关闭对于用户直观的显示是如何操作的呢?也就是在状态栏上的显示如何更新:在SystemUI上VOLTE图标的显示是通过监听PhoneStateListener的状态来改变的,是在frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\MobileSignalController.java中进行监听的,代码如下:
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();
}
@Override
public void onServiceStateChanged(ServiceState state) {
if (DEBUG) {
Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+ " dataState=" + state.getDataRegState());
}
mServiceState = state;
mDataNetType = state.getDataNetworkType();
/// M: Support 4G+ icon.
mDataNetType =
NetworkTypeUtils.getDataNetTypeFromServiceState(mDataNetType, mServiceState);
updateTelephony();
}
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
if (DEBUG) {
Log.d(mTag, "onDataConnectionStateChanged: state=" + state
+ " type=" + networkType);
}
mDataState = state;
mDataNetType = networkType;
/// M: Support 4G+ icon.
mDataNetType =
NetworkTypeUtils.getDataNetTypeFromServiceState(mDataNetType, mServiceState);
updateTelephony();
}
@Override
public void onDataActivity(int direction) {
if (DEBUG) {
Log.d(mTag, "onDataActivity: direction=" + direction);
}
setActivity(direction);
}
@Override
public void onCarrierNetworkChange(boolean active) {
if (DEBUG) {
Log.d(mTag, "onCarrierNetworkChange: active=" + active);
}
mCurrentState.carrierNetworkChangeMode = active;
updateTelephony();
}
};
在以上的onServiceStateChanged与onDataConnectionStateChanged方法中SIM卡的数据状态发生变化时就会改变mDataNetType的值,然后通过updateTelephony()方法来更新数据状态的变化而改变Systemui的网络状态的显示,updateTelephony()更新VOLTE如下:
private final void updateTelephony() {
........
if (!mCurrentState.isOverwfc) {
mCurrentState.volteIcon = mCurrentState.imsRegState == ServiceState.STATE_IN_SERVICE
&& isLteNetWork() ? NetworkTypeUtils.VOLTE_ICON : 0;
}
notifyListenersIfNecessary();
}
public boolean isLteNetWork() {
return (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE
|| mDataNetType == TelephonyManager.NETWORK_TYPE_LTEA);
}
然后通过调用MobileSignalController.java的notifyListenersIfNecessary()最后调用MobileSignalController.java的notifyListeners()方法 更新图标显示,代码如下:
@Override
public void notifyListeners(SignalCallback callback) {
MobileIconGroup icons = getIcons();
........
callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, networkIcon, volteIcon,
qsTypeIcon, activityIn, activityOut, dataContentDescription, description,
icons.mIsWide, mSubscriptionInfo.getSubscriptionId());
/** @ }*/
/// M: update plmn label @{
mNetworkController.refreshPlmnCarrierLabel();
/// @}
}
通过callback.setMobileDataIndicators(),去调用frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\SignalClusterView.java的setMobileDataIndicators方法:
@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) {
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;
state.mNetworkIcon = networkType;
state.mVolteIcon = volteIcon;
/// M: Add for plugin features. @ {
state.mDataActivityIn = activityIn;
state.mDataActivityOut = activityOut;
/// @ }
apply();
}
private void setCustomizeViewProperty() {
// Add for [Network Type on Statusbar], the place to set network type icon.
setNetworkIcon();
/// M: Add for volte icon.
setVolteIcon();
}
private void setVolteIcon() {
if (mVolteIcon == 0) {
mVolteType.setVisibility(View.GONE);
} else {
mVolteType.setImageResource(mVolteIcon);
mVolteType.setVisibility(View.VISIBLE);
}
/// M: customize VoLTE icon. @{
mStatusBarExt.setCustomizedVolteView(mVolteIcon, mVolteType);
/// M: customize VoLTE icon. @}
}
判断假如mVolteIcon是否为0,为0代表当前不是VOLTE,不为0代表当前为VOLTE状态。