Android指令处理流程源码追踪

来源:互联网 发布:java程序调试步骤 编辑:程序博客网 时间:2024/05/29 19:05

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>







0 0
原创粉丝点击