Android call setting 源码分析 从顶层到底层(上)

Android 的 call setting 是用来设定与 simcard 相关的一些内容的应用程序,如网络,PIN等等,算是AP层。这里就选择其中一个项从源代码读下去直到底层,看看大概的结构和流程。

在 Android 主菜单中选择 setting->call setting->additional call setting->caller ID,会弹出来一个对话框来选择,这个项是用来设定在用电话本拨打电话的时候是否显示对方的电话号码。这里就以这个设定为例来一步步读下去。

 

AP层:

call setting 的代码和资源都是放在/packages/apps/Phone 的目录下。其实 Android 的 setting AP 相关的资源都是放在/packages/apps/setting 下的。但是看 /packages/apps/Settings/res/xml/settings.xml 中:


<PreferenceScreen android:key="call_settings" android:title="@string/call_settings_title"android:summary="@string/call_settings_summary">

< intent  android:action =" android.intent.action.MAIN "  android:targetPackage =" com.android.phone " android:targetClass =" com.android.phone.CallFeaturesSetting "  />
</ PreferenceScreen >

从这里就可以知道,android 的call setting 的包指向了 phone,并且知道了入口是 CallFeaturesSetting 类。
在/packages/apps/Phone/res/call_featrue_setting.xml 中有call setting 的界面布局:
< PreferenceScreen   android:key =" button_more_expand_key "  android:title ="@string/ labelMore " android:persistent ="false">
...

 

< ListPreference   android:key =" button_clir_key " ... />
这个button_clir_key就是对应的 caller ID 的那个按钮,从这里可以看出是一个ListPreference,点击会出现一个列表框。里面出现的内容布局都在这里定义。相关的xml档都在/packages/apps/Phone/res 下。
接着就是AP的代码了,在/packages/apps/Phone/src 下。前面说了入口是 CallFeaturesSetting:
public class CallFeaturesSetting extends PreferenceActivity {

   …

   private PreferenceScreen mSubMenuFDNSettings;

   private ListPreference mButtonCLIR;

   private CheckBoxPreference mButtonCW;

...

protected void onCreate(…) {

  

   PreferenceScreen prefSet = getPreferenceScreen();

   mButtonCLIR  =   (ListPreference) prefSet.findPreference(BUTTON_CLIR_KEY);

...

定义的 mButtonCLIR 就是对应caller ID 的变量。在onCreate中初始化,用findPreference来找到XML中对应的资源。

然后是对这个按钮的响应代码:


public boolean onPreferenceChange(Preference preference, Object objValue){

  if (preference == mButtonCLIR) {

handleCLIRClickRequest(mButtonCLIR.findIndexOfValue((String) objValue));

...

}

private void handleCLIRClickRequest(int i) {

  

   mPhone.setOutgoingCallerIdDisplay(i,Message.obtain(mSetOptionComplete, EVENT_CLIR_EXECUTED));

}

 

可以看到最终是调用 mPhone.setOutgoingCallerIdDisplay 来完成真正的设定。这个 mPhone 是

com.android.internal.telephony.Phone,mPhone 的调用就进入 framework 层了。

 

Framework层:

相关的代码在/frameworks/base/telephony/java 中。先从 Phone 开始,这是一个 interface,真正实现是在

com.android.internal.telephony.gsm.GSMPhone 中:

 

public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete) { mCM.setCLIR(commandInterfaceCLIRMode, h.obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete)); }

 

这里调用 mCM.setCLIR。mCM 是一个 CommandsInterface,真正实现是在 RIL.java 文件中。这下到了framework中

真正办实事的地方。同样是在com.android.internal.telephony.gsm 下,RIL类中:


public void setCLIR(int clirMode, Message result)

{ RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result); rr.mp.writeInt(1); rr.mp.writeInt(clirMode);

... send(rr); }

 

这里顺便说一下,RIL与底层是用socket来通信。所以send(rr)最终是把RIL_REQUEST_SET_CLIR发给底层,底层会有一个守护

进程来接收framework层的信息,并且把结果传达上去。继续看下send的代码:

 

private void send(RILRequest rr) { Message msg; msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); }

 

发一个EVENT_SEND的message给系统。那么找这个 handle 这个 message 的地方,还是同一个文件里,RIL.RILSender类

里面的handleMessage:

 

public void  handleMessage(Message msg)

{

RILRequest rr = (RILRequest)(msg.obj);

switch (msg.what) { case EVENT_SEND:

LocalSocket s; s = mSocket;

... byte[] data; data = rr.mp.marshall(); rr.mp.recycle(); rr.mp = null; // parcel length in big endian dataLength[0] = dataLength[1] = 0; dataLength[2] = (byte)((data.length >> 8) & 0xff); dataLength[3] = (byte)((data.length) & 0xff); s.getOutputStream().write(dataLength); s.getOutputStream().write(data);

...

 

这里的mSocket 在就是与底层沟通的socket,有兴趣可以看看相关代码。

到这里 framework 层也算告一段落,在下去就是底层的C部分了。放在下一篇文章在写吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android码出现"Traceback (most recent call last)"的错误通常是因为代码中出现了异常,导致程序崩溃或无法正常执行。这个错误提示是Python解释器在执行代码时遇到异常时输出的错误信息。具体的错误原因可能因情况而异,需要查看完整的错误信息才能确定。 根据提供的引用内容,出现"Traceback (most recent call last)"的错误可能是由于缺少相关的模块或库导致的。在这种情况下,应该检查是否安装了相应的模块或库。引用中的错误信息"No module named matplotlib"表明缺少matplotlib模块,而引用给出了解决办法,即使用pip命令安装matplotlib模块。 要解决Android码出现"Traceback (most recent call last)"错误,需要进一步查看完整的错误信息,并根据具体情况采取适当的措施。可能的解决办法包括: 1. 检查所需的库和模块是否已正确安装,并确保它们可以在代码中正确导入。 2. 检查代码中是否存在语法错误、变量命名错误或其他逻辑错误,并进行相应的修复。 3. 使用调试工具或日志记录来识别代码中的问题,并进行相应的调试和修复。 请注意,以上解决办法仅是一般性建议,具体的解决方法应根据具体情况进行调整。如果问题仍然存在,建议提供更详细的错误信息以便更准确地帮助您解决问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Traceback (most recent call last): File ““, line 1, in <module> ImportError: No module name](https://blog.csdn.net/qq_45771209/article/details/108672989)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [安卓4.0码编译问题](https://download.csdn.net/download/xiaozheng_apk/5011446)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值