张店网站建设方案淘城汇网站谁做的
一、组件职责与定位
| 组件 | 所在进程 | 核心职责 | 关键特性 | 
|---|---|---|---|
| CallsManager | Telecom系统进程 | 通话状态机核心:管理所有Call对象的生命周期(创建、状态更新、销毁)。监听Call状态变化并通知所有观察者(如InCallController)。 | 通过mListeners集合维护观察者列表(如InCallController、Ringer等)。 | 
| InCallController | Telecom系统进程 | 跨进程通信桥梁:监听CallsManager的Call事件,绑定InCallService服务(如InCallServiceImpl)。将Call状态封装为ParcelableCall对象传递给UI进程。 | 通过bindServiceAsUser()绑定InCallService,触发UI进程启动。 | 
| InCallPresenter | Dialer应用进程 | MVP模式中的Presenter:接收InCallService的Call状态更新,控制InCallActivity的创建/销毁。管理子Presenter(如CallCardPresenter)和界面逻辑。 | 通过InCallAdapter将用户操作(接听/挂断)转发给CallsManager。 | 
| InCallActivity | Dialer应用进程 | 界面容器:承载通话UI的Activity,动态加载Fragment(如CallCardFragment)。仅响应界面事件,业务逻辑委托给InCallPresenter。 | 布局仅为FrameLayout,具体UI由Fragment实现。 | 
二、核心交互流程(以去电MO为例)
-  
Call创建与状态同步
CallsManager创建Call对象,触发onCallAdded回调。InCallController监听到事件,绑定InCallService服务(跨进程)。- 绑定成功后,
InCallServiceImpl通知InCallPresenter启动InCallActivity。 
 -  
界面启动与用户操作
InCallPresenter调用startActivity()启动InCallActivity,加载通话UI。- 用户点击“拨号”后,
InCallPresenter通过InCallAdapter调用CallsManager.placeOutgoingCall()。 
 -  
底层通话建立
CallsManager通过ConnectionService与Modem交互,Call状态变为DIALING→ACTIVE。- 状态变化经
InCallController同步至UI进程,触发InCallPresenter更新界面(如显示通话计时)。 
 
三、与Call对象的交互关系
-  
Call的生命周期管理
- 创建:
CallsManager在去电/来电时创建Call对象,分配唯一ID。 - 状态流转:Call状态(
DIALING、RINGING、ACTIVE等)由CallsManager驱动,通过setCallState()更新。 - 销毁:通话结束时,
CallsManager移除Call并触发onCallRemoved。 
 - 创建:
 -  
Call数据的跨进程传递
InCallController将Call转换为ParcelableCall(可序列化对象),通过Binder传递至UI进程。InCallPresenter解析ParcelableCall,更新界面元素(如联系人姓名、通话时长)。
 -  
用户操作与Call状态联动
- 接听/挂断等操作通过
InCallAdapter回调至CallsManager,后者调用Call.answer()或Call.disconnect()。 - 状态变化反向同步至UI,形成闭环(例如挂断后界面关闭)。
 
 - 接听/挂断等操作通过
 
四、设计特点与架构价值
-  
分层解耦
- 上层(UI层):
InCallActivity仅负责渲染,InCallPresenter处理逻辑,符合MVP模式。 - 下层(服务层):
CallsManager专注状态机,InCallController处理跨进程通信。 
 - 上层(UI层):
 -  
跨进程高效同步
- 通过Binder机制实现Telecom进程与Dialer进程的实时状态同步(
ParcelableCall序列化)。 
 - 通过Binder机制实现Telecom进程与Dialer进程的实时状态同步(
 -  
可扩展性
CallsManager的监听器模式支持动态添加组件(如Ringer振铃模块、CallAudioManager音频控制)。InCallPresenter可管理多类子Presenter,适应不同通话场景(如视频通话、会议)。
 
五、链路
这一架构通过状态驱动(CallsManager)与界面逻辑分离(MVP模式)实现高内聚低耦合:
- 核心链路:
CallsManager → InCallController → InCallPresenter → InCallActivity构成状态传递闭环; - 交互本质:Call对象作为载体,在进程间传递状态,驱动UI与底层服务协同。
其设计充分体现了Android系统服务的模块化思想,为通话功能提供了稳定可扩展的基础。 
六、Call 状态
1. DIALING(拨号中)
- 定义:用户发起呼叫后,系统开始连接对方但尚未接通的阶段。
 - 触发时机: 
- 用户拨号后立即进入此状态,无论是否开始响铃。
 - 若需选择通话账户(如VoIP或SIM卡),会先进入
SELECT_PHONE_ACCOUNT状态,确认后转为DIALING。 
 - 行为特征: 
- 主叫方听回铃音或等待提示音,被叫方设备未响铃。
 - 若拨号失败(如无信号),会转为
DISCONNECTED(连接断开)。 
 
2. RINGING(响铃中)
- 定义:被叫方收到来电请求,设备开始响铃或震动的状态。
 - 触发时机: 
- 主叫方拨号后,被叫方网络收到呼叫请求时触发。
 - 若被叫方正在通话中,此状态可能伴随
CALL_WAITING(呼叫等待)提示。 
 - 行为特征: 
- 被叫方设备响铃,显示来电界面。
 - 主叫方仍处于
DIALING状态,直至被叫方接听。 
 
3. ACTIVE(通话中)
- 定义:双方已建立连接,可实时双向通话。
 - 触发时机: 
- 被叫方接听来电后,主被叫双方均进入此状态。
 - 从
HOLDING(通话保持)状态恢复时也会切换至此。 
 - 行为特征: 
- 通话计时器启动,界面显示通话时长。
 - 支持操作如静音(
MUTE)、保持(HOLD)、多方通话等。 
 
4. HOLDING(保持中)
- 通话被主动暂停(如接听新来电),双方暂时中断语音连接。
 - 界面显示“已保持”,恢复后回到
ACTIVE。 
5. DISCONNECTING(断开中)
- 用户挂断电话后,系统释放资源的中间状态,随后转为
DISCONNECTED。 
6. DISCONNECTED(已断开)
- 通话完全结束,资源已释放。界面显示挂断提示(如通话时长总结)。
 
7. CALL_WAITING(呼叫等待)
- 用户通话中时第三方来电,当前通话保持,新来电进入
RINGING状态。 
状态转换关系
通话状态的典型生命周期流程如下:
- 特殊场景: 
- 通话保持时新来电:
ACTIVE → HOLDING(原通话) +RINGING(新来电)。 - 拨号失败:
DIALING → DISCONNECTED。 
 - 通话保持时新来电:
 
各个层的差异
| DriverCall.State | Call.State(opt/telephony) | Connection.State(base/telecomm) | CallState(services/Telecomm) | Call.State(base/telecomm) | Call.State(Dialler) | 
|---|---|---|---|---|---|
| ACTIVE | ACTIVE | STATE_ACTIVE | ACTIVE | STATE_ACTIVE | ACTIVE | 
| HOLDING | HOLDING | STATE_HOLDING | ON_HOLD | STATE_HOLDING | ONHOLD | 
| DIALING | DIALING | STATE_DIALING | DIALING | STATE_DIALING | DIALING | 
| ALERTING | ALERTING | RINGALERTING | |||
| INCOMING | INCOMING | STATE_RINGING | RINGING | STATE_RINGING | INCOMING | 
| WAITING | WAITING | CALL_WAITING | |||
| IDLE | IDLE | ||||
| DISCONNECTED | STATE_DISCONNECTED | DISCONNECTED | STATE_DISCONNECTED | DISCONNECTED | |
| DISCONNECTING | DISCONNECTING | STATE_DISCONNECTING | DISCONNECTING | ||
| STATE_INITIALIZING | CONNECTING | STATE_CONNECTING | CONNECTING | ||
| STATE_NEW | NEW | STATE_NEW | |||
| STATE_PULLING_CALL | STATE_PULLING_CALL | ||||
| SELECT_PHONE_ACCOUNT | STATE_SELECT_PHONE_ACCOUNT | SELECT_PHONE_ACCOUNT | |||
| ABORTED | STATE_DISCONNECTED | DISCONNECTED | |||
| STATE_PRE_DIAL_WAIT | |||||
| INVALID | |||||
| CONFERENCED | |||||
| BLOCKED | |||||
| WAIT_ACCOUNT_RESPONSE | 
七、MT 与 MO
在Android通话系统中,MO(Mobile Originated,移动始发)和MT(Mobile Terminated,移动终止) 分别指代用户主动拨打电话(主叫)和接听来电(被叫)的流程。
1. MO(去电流程)
定义:用户主动发起呼叫的过程,即“拨打电话”。
 核心步骤:
- 拨号触发:用户在Dialer应用的拨号界面(
DialpadFragment)点击拨号按钮,通过Intent.ACTION_CALL发起请求。 - 权限检查: 
- 系统检查
CALL_PHONE权限及默认拨号器身份(TelecomUtil.hasCallPhonePermission())。 - 紧急呼叫(如
ACTION_CALL_EMERGENCY)绕过权限限制。 
 - 系统检查
 - Telecom服务处理: 
TelecomServiceImpl.placeCall()验证号码合法性,并通过CallsManager创建通话对象(Call)。
 - UI启动与状态更新: 
- 系统启动
InCallActivity,根据通话状态(如DIALING)显示拨号界面。 - 底层Modem返回
DIALING状态后,界面更新为拨号中。 
 - 系统启动
 - 呼叫建立: 
- 被叫方接听后,状态转为
ACTIVE,通话计时开始。 
 - 被叫方接听后,状态转为
 
流程图简化:

2. MT(来电流程)
定义:用户接收来电并接听的过程,即“接听电话”。
 核心步骤:
- 来电通知: 
- Modem检测到来电,通过RIL层上报
RINGING状态至CallsManager。 
 - Modem检测到来电,通过RIL层上报
 - 铃声与震动: 
CallNotifier调用Ringer播放铃声(非DIALING状态独有)。
 - UI启动: 
- 系统启动
InCallActivity,显示来电界面(如联系人信息、接听/挂断按钮)。 
 - 系统启动
 - 用户响应: 
- 接听:状态转为
ACTIVE,建立双向通话。 - 拒接:状态转为
DISCONNECTED。 
 - 接听:状态转为
 
流程图简化:
3. MO与MT的核心区别
| 维度 | MO(主叫) | MT(被叫) | 
|---|---|---|
| 触发起点 | 用户主动拨号 | 网络侧下发来电请求 | 
| 关键状态 | DIALING(拨号中) | RINGING(响铃中) | 
| 系统组件 | DialpadFragment触发Intent | RIL/CallsManager检测来电状态 | 
| 特殊处理 | 紧急呼叫权限绕过 | 铃声播放(Ringer) | 
| VoLTE角色 | 主叫UE构造SIP INVITE | 被叫S-CSCF触发业务逻辑(如彩铃) | 
注意点
- MO:用户拨号 → 权限检查 → Telecom处理 → 界面显示
DIALING→ 通话建立(ACTIVE)。 - MT:网络下发来电 → 播放铃声 → 界面显示
RINGING→ 用户接听(ACTIVE)或拒接(DISCONNECTED)。
本质差异在于触发源(用户主动 vs. 网络被动)和核心状态(DIALINGvs.RINGING)。理解两者区别对开发通话功能、优化用户体验及设计测试用例至关重要。 
