一个小需求,如题,但是我在搜索引擎上几乎搜不到相关文章,就权作记录一下,下次再遇到这个需求也不用从头撸源码看下来。
首先,找到CarrierText
类,这是系统写的一个自定义的TextView类,无服务的提示都是使用这个view显示的,那么我们就不需要在XML那边处理几个不同的页面了,只需要处理根源处,一了百了。
虽然代码有五百行,但是逻辑简单,就不一个函数一个函数的解释了。找到updateCarrierText
函数,这个函数里设置文字提示,不管里面的各种判断,在最后setText(displayText);
的前面修改这个displayText
内容就行了。
源码与修改如下
protected void updateCarrierText() {
boolean allSimsMissing = true;
boolean anySimReadyAndInService = false;
CharSequence displayText = null;
List<SubscriptionInfo> subs = mKeyguardUpdateMonitor.getSubscriptionInfo(false);
final int N = subs.size();
if (DEBUG) Log.d(TAG, "updateCarrierText(): " + N);
for (int i = 0; i < N; i++) {
int subId = subs.get(i).getSubscriptionId();
State simState = mKeyguardUpdateMonitor.getSimState(subId);
CharSequence carrierName = subs.get(i).getCarrierName();
CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
if (DEBUG) {
Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
}
if (carrierTextForSimState != null) {
allSimsMissing = false;
displayText = concatenate(displayText, carrierTextForSimState);
}
if (simState == IccCardConstants.State.READY) {
ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
if (ss != null && ss.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
// hack for WFC (IWLAN) not turning off immediately once
// Wi-Fi is disassociated or disabled
if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
|| (mWifiManager.isWifiEnabled()
&& mWifiManager.getConnectionInfo() != null
&& mWifiManager.getConnectionInfo().getBSSID() != null)) {
if (DEBUG) {
Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
}
anySimReadyAndInService = true;
}
}
}
}
if (allSimsMissing) {
if (N != 0) {
// Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
// This depends on mPlmn containing the text "Emergency calls only" when the radio
// has some connectivity. Otherwise, it should be null or empty and just show
// "No SIM card"
// Grab the first subscripton, because they all should contain the emergency text,
// described above.
displayText = makeCarrierStringOnEmergencyCapable(
getMissingSimMessage(), subs.get(0).getCarrierName());
} else {
// We don't have a SubscriptionInfo to get the emergency calls only from.
// Grab it from the old sticky broadcast if possible instead. We can use it
// here because no subscriptions are active, so we don't have
// to worry about MSIM clashing.
CharSequence text =
getContext().getText(com.android.internal.R.string.emergency_calls_only);
Intent i = getContext().registerReceiver(null,
new IntentFilter(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION));
if (i != null) {
String spn = "";
String plmn = "";
if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
spn = i.getStringExtra(TelephonyIntents.EXTRA_SPN);
}
if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
plmn = i.getStringExtra(TelephonyIntents.EXTRA_PLMN);
}
if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
if (Objects.equals(plmn, spn)) {
text = plmn;
} else {
text = concatenate(plmn, spn);
}
}
displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
}
}
displayText = updateCarrierTextWithSimIoError(displayText, allSimsMissing);
// APM (airplane mode) != no carrier state. There are carrier services
// (e.g. WFC = Wi-Fi calling) which may operate in APM.
if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
displayText = getAirplaneModeMessage();
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//禁止在锁屏界面左上角状态栏和下拉状态栏底部显示"没有 SIM 卡 - 无服务"的提示
displayText = "";
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
setText(displayText);
}