1.拨号界面输入*#06#,显示IMEI号,这是怎么出来的?
2.如何快速的找出Android平台中的指令?
1. 在DialpadFragment中的EditText注册一个Textchanged的监听器TextWatcher,
当EditText中的内容发生变化时会调用相应的回调函数,TextWatcher是一个接口:
public interface TextWatcher extends NoCopySpan { public void beforeTextChanged(CharSequence s, int start,int count, int after); public void onTextChanged(CharSequence s, int start, int before, int count); public void afterTextChanged(Editable s); }在DialpadFragment中实现了该接口:
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); }else { mDigits.setCursorVisible(true); } updateDialAndDeleteButtonEnabledState(); loadSmartDialEntries(); refreshDigitTextSize(input); }指令处理的主角:SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)
看 其方法的主体:
static boolean handleChars(Context context, String input, boolean useSystemWindow, EditText textField) { //get rid of the separators so that the string gets parsed correctly String dialString = PhoneNumberUtils.stripSeparators(input); if (handlePRLVersion(context, dialString) || handleModemTestDisplay(context, dialString) || handleIMEIDisplay(context, dialString, useSystemWindow) || handleRegulatoryInfoDisplay(context, dialString) || handlePinEntry(context, dialString) || handleAdnEntry(context, dialString, textField) || handleSecretCode(context, dialString) return true; } return false; }这里有个handleIMEIDisplay(context, dialString, useSystemWindow),看其主体:
static boolean handleIMEIDisplay(Context context, String input, boolean useSystemWindow) { if (input.equals(MMI_IMEI_DISPLAY)) { <span style="color:#3333ff;"> //</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="color:#3333ff;">MMI_IMEI_DISPLAY = "*#06#"</span></span> if (MSimTelephonyManager.getDefault().isMultiSimEnabled()) { return handleMSimIMEIDisplay(context);<span style="background-color: rgb(255, 255, 255);"><span style="color:#3333ff;">//显示IMEI号</span></span> } int subscription = MSimTelephonyManager.getDefault().getPreferredVoiceSubscription(); int phoneType; if (MSimTelephonyManager.getDefault().isMultiSimEnabled()) { phoneType = ((MSimTelephonyManager)context.getSystemService( Context.MSIM_TELEPHONY_SERVICE)).getCurrentPhoneType(subscription); } else { phoneType = ((TelephonyManager)context.getSystemService( Context.TELEPHONY_SERVICE)).getCurrentPhoneType(); } if (phoneType == TelephonyManager.PHONE_TYPE_GSM) { showIMEIPanel(context, useSystemWindow);<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color:#3333ff;">//显示IMEI号</span></span> return true; } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) { showMEIDPanel(context, useSystemWindow);<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color:#3333ff;">//显示IMEI号</span></span> return true; } } return false; }至此IMEI号的显示流程都呈现出来。
2.在handleChars中还有对其他指令进行处理的方法:
handleModemTestDisplay、handleRegulatoryInfoDisplay、handleSecretCode等,
其中handleSecretCode是对*#*#。。#*#* 这一类的指令进行集中处理,看源码:
static boolean handleSecretCode(Context context, String input) { // Secret codes are in the form *#*#<code>#*#* int len = input.length(); if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) { Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION, Uri.parse("android_secret_code://" + input.substring(4, len - 4))); context.sendBroadcast(intent); return true; } return false; }可以看到是发送的一个广播,广播的action是 :
public static final String SECRET_CODE_ACTION ="android.provider.Telephony.SECRET_CODE";
data是一个URI,
所以在平台里面的所有AndroidManifest.xml 文件中查找android.provider.Telephony.SECRET_CODE,
即可找出平台中所有*#*#。。#*#* 类型的指令,如:
<receiver android:name="TestingSettingsBroadcastReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> <data android:scheme="android_secret_code" android:host="837851" /> </intent-filter> </receiver>
<receiver android:name="TestingSettingsBroadcastReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> <data android:scheme="android_secret_code" android:host="4636" /> </intent-filter> </receiver>