在今天的培训会议上,在拨号盘里输入一组有规律的数字就能启动一个程序,于是看看源代码,加深一下理解。
比如要查看IMEI码,只需在拨号盘里输入*#06#。就能看到手机的IMEI码,由于我的手机是直接从工厂拿过来的IMEI码为null。
回顾主题,拨号盘的界面是在DialpadFragment,当用户输入号码的过程实际上市改变输入框的EditText,他继承了接口:
TextWatcher`
`class DialpadFragment extends AnalyticsFragment
implements View.OnClickListener,
View.OnLongClickListener, View.OnKeyListener,
AdapterView.OnItemClickListener, ***TextWatcher***,
PopupMenu.OnMenuItemClickListener,
DialpadKeyButton.OnPressedListener, DialpadExtensionAction {
TextWatcher的接口方法:
@Override
public void afterTextChanged(Editable input) {
// When DTMF dialpad buttons are being pressed, we delay SpecialCharSequencMgr sequence,
// since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down"
// behavior.
if (!mDigitsFilledByIntent &&
**SpecialCharSequenceMgr.handleChars(**getActivity(), input.toString(), mDigits)) {
// A special sequence was entered, clear the digits
mDigits.getText().clear();
}
if (isDigitsEmpty()) {
mDigitsFilledByIntent = false;
mDigits.setCursorVisible(false);
}
if (mDialpadQueryListener != null) {
mDialpadQueryListener.onDialpadQueryChanged(mDigits.getText().toString());
}
updateDeleteButtonEnabledState();
}
“`
继续向下追溯,handlechars静态方法有重载机制。参数不同,相互调用,这在java里非常常见。
static boolean handleChars(Context context, String input, boolean useSystemWindow,
EditText textField) {
/// M: for ALPS01692450 @{
// check null
if(context == null) {
return false;
}
/// @}
//get rid of the separators so that the string gets parsed correctly
String dialString = PhoneNumberUtils.stripSeparators(input);
if (***handleIMEIDisplay***(context, dialString, useSystemWindow)
|| handleRegulatoryInfoDisplay(context, dialString)
|| handlePinEntry(context, dialString)
|| handleAdnEntry(context, dialString, textField)
|| handleSecretCode(context, dialString)) {
return true;
}
return false;
}
static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) {
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) {
**showDeviceIdPanel(context, telephonyManager);**
return true;
}
return false;
}
在if语句中,有一个常量MMI_IMEI_DISPLAY,找到他的声明部分
private static final String MMI_IMEI_DISPLAY = "*#06#";
所以说当满足条件后就调用showDeviceIdPanel(context, telephonyManager)方法
/**
* Show an alert dialog, the content is IMEI/MEID list of the device
* @param context
* @param telephonyManager
*/
private static void showDeviceIdPanel(Context context, TelephonyManager telephonyManager) {
final int phoneType = telephonyManager.getPhoneType();
final int titleId = (phoneType == TelephonyManager.PHONE_TYPE_GSM) ? R.string.imei : R.string.meid;
int[] slotIds = getSlotIds();
String imei_invalid = context.getResources().getString(R.string.imei_invalid);
List<String> imeis = new ArrayList<String>();
for (int slotId : slotIds) {
String imei = telephonyManager.getDeviceId(slotId);
imeis.add(TextUtils.isEmpty(imei) ? imei_invalid : imei);
}
/** M: Feature patch back, add support diplay one IMEI @{ */
if (DialerFeatureOptions.isSigleImeiEnabled()) {
AlertDialog alert = new AlertDialog.Builder(context).setTitle(titleId)
.setMessage(imeis.get(0))
.setPositiveButton(android.R.string.ok, null)
.setCancelable(false)
.show();
} else {
AlertDialog alert = new AlertDialog.Builder(context).setTitle(titleId)
.setItems(imeis.toArray(new String[imeis.size()]), null)
.setPositiveButton(android.R.string.ok, null)
.setCancelable(false)
.show();
}
/** @} */
}
看到注释,我们就知道这个方法是干啥的,它弹出一个对话框,显示IMEI号。这里需要说明一点的是:本例中弹出一个对话框作为最终处理,其实android 中经常 发个广播来启动隐藏的应用。