android 之 CALL

一、组件职责与定位

组件所在进程核心职责关键特性
CallsManagerTelecom系统进程通话状态机核心:管理所有Call对象的生命周期(创建、状态更新、销毁)。监听Call状态变化并通知所有观察者(如InCallController)。通过mListeners集合维护观察者列表(如InCallControllerRinger等)。
InCallControllerTelecom系统进程跨进程通信桥梁:监听CallsManager的Call事件,绑定InCallService服务(如InCallServiceImpl)。将Call状态封装为ParcelableCall对象传递给UI进程。通过bindServiceAsUser()绑定InCallService,触发UI进程启动。
InCallPresenterDialer应用进程MVP模式中的Presenter:接收InCallService的Call状态更新,控制InCallActivity的创建/销毁。管理子Presenter(如CallCardPresenter)和界面逻辑。通过InCallAdapter将用户操作(接听/挂断)转发给CallsManager
InCallActivityDialer应用进程界面容器:承载通话UI的Activity,动态加载Fragment(如CallCardFragment)。仅响应界面事件,业务逻辑委托给InCallPresenter布局仅为FrameLayout,具体UI由Fragment实现。

二、核心交互流程(以去电MO为例)

  1. Call创建与状态同步

    • CallsManager创建Call对象,触发onCallAdded回调。
    • InCallController监听到事件,绑定InCallService服务(跨进程)。
    • 绑定成功后,InCallServiceImpl通知InCallPresenter启动InCallActivity
  2. 界面启动与用户操作

    • InCallPresenter调用startActivity()启动InCallActivity,加载通话UI。
    • 用户点击“拨号”后,InCallPresenter通过InCallAdapter调用CallsManager.placeOutgoingCall()
  3. 底层通话建立

    • CallsManager通过ConnectionService与Modem交互,Call状态变为DIALINGACTIVE
    • 状态变化经InCallController同步至UI进程,触发InCallPresenter更新界面(如显示通话计时)。
用户操作 InCallActivity InCallPresenter InCallAdapter CallsManager InCallController InCallService 点击拨号 onUserAction(拨号) placeOutgoingCall() placeOutgoingCall() 更新Call状态 onCallAdded(Call) addCall(ParcelableCall) onCallAdded() 刷新界面(计时/状态) 用户操作 InCallActivity InCallPresenter InCallAdapter CallsManager InCallController InCallService

三、与Call对象的交互关系

  1. Call的生命周期管理

    • 创建CallsManager在去电/来电时创建Call对象,分配唯一ID。
    • 状态流转:Call状态(DIALINGRINGINGACTIVE等)由CallsManager驱动,通过setCallState()更新。
    • 销毁:通话结束时,CallsManager移除Call并触发onCallRemoved
  2. Call数据的跨进程传递

    • InCallController将Call转换为ParcelableCall(可序列化对象),通过Binder传递至UI进程。
    • InCallPresenter解析ParcelableCall,更新界面元素(如联系人姓名、通话时长)。
  3. 用户操作与Call状态联动

    • 接听/挂断等操作通过InCallAdapter回调至CallsManager,后者调用Call.answer()Call.disconnect()
    • 状态变化反向同步至UI,形成闭环(例如挂断后界面关闭)。

四、设计特点与架构价值

  1. 分层解耦

    • 上层(UI层)InCallActivity仅负责渲染,InCallPresenter处理逻辑,符合MVP模式。
    • 下层(服务层)CallsManager专注状态机,InCallController处理跨进程通信。
  2. 跨进程高效同步

    • 通过Binder机制实现Telecom进程与Dialer进程的实时状态同步(ParcelableCall序列化)。
  3. 可扩展性

    • 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状态。
状态转换关系

通话状态的典型生命周期流程如下:

被叫方响应
被叫方接听
用户点击保持
恢复通话
挂断
DIALING
RINGING
ACTIVE
HOLDING
DISCONNECTING
DISCONNECTED
  • 特殊场景
    • 通话保持时新来电:ACTIVE → HOLDING(原通话) + RINGING(新来电)。
    • 拨号失败:DIALING → DISCONNECTED
各个层的差异
DriverCall.StateCall.State(opt/telephony)Connection.State(base/telecomm)CallState(services/Telecomm)Call.State(base/telecomm)Call.State(Dialler)
ACTIVEACTIVESTATE_ACTIVEACTIVESTATE_ACTIVEACTIVE
HOLDINGHOLDINGSTATE_HOLDINGON_HOLDSTATE_HOLDINGONHOLD
DIALINGDIALINGSTATE_DIALINGDIALINGSTATE_DIALINGDIALING
ALERTINGALERTINGRINGALERTING
INCOMINGINCOMINGSTATE_RINGINGRINGINGSTATE_RINGINGINCOMING
WAITINGWAITINGCALL_WAITING
IDLEIDLE
DISCONNECTEDSTATE_DISCONNECTEDDISCONNECTEDSTATE_DISCONNECTEDDISCONNECTED
DISCONNECTINGDISCONNECTINGSTATE_DISCONNECTINGDISCONNECTING
STATE_INITIALIZINGCONNECTINGSTATE_CONNECTINGCONNECTING
STATE_NEWNEWSTATE_NEW
STATE_PULLING_CALLSTATE_PULLING_CALL
SELECT_PHONE_ACCOUNTSTATE_SELECT_PHONE_ACCOUNTSELECT_PHONE_ACCOUNT
ABORTEDSTATE_DISCONNECTEDDISCONNECTED
STATE_PRE_DIAL_WAIT
INVALID
CONFERENCED
BLOCKED
WAIT_ACCOUNT_RESPONSE

七、MT 与 MO

在Android通话系统中,MO(Mobile Originated,移动始发)和MT(Mobile Terminated,移动终止) 分别指代用户主动拨打电话(主叫)和接听来电(被叫)的流程。

1. MO(去电流程)

定义:用户主动发起呼叫的过程,即“拨打电话”。
核心步骤

  1. 拨号触发:用户在Dialer应用的拨号界面(DialpadFragment)点击拨号按钮,通过Intent.ACTION_CALL发起请求。
  2. 权限检查
    • 系统检查CALL_PHONE权限及默认拨号器身份(TelecomUtil.hasCallPhonePermission())。
    • 紧急呼叫(如ACTION_CALL_EMERGENCY)绕过权限限制。
  3. Telecom服务处理
    • TelecomServiceImpl.placeCall()验证号码合法性,并通过CallsManager创建通话对象(Call)。
  4. UI启动与状态更新
    • 系统启动InCallActivity,根据通话状态(如DIALING)显示拨号界面。
    • 底层Modem返回DIALING状态后,界面更新为拨号中。
  5. 呼叫建立
    • 被叫方接听后,状态转为ACTIVE,通话计时开始。

流程图简化

在这里插入图片描述

2. MT(来电流程)

定义:用户接收来电并接听的过程,即“接听电话”。
核心步骤

  1. 来电通知
    • Modem检测到来电,通过RIL层上报RINGING状态至CallsManager
  2. 铃声与震动
    • CallNotifier调用Ringer播放铃声(非DIALING状态独有)。
  3. UI启动
    • 系统启动InCallActivity,显示来电界面(如联系人信息、接听/挂断按钮)。
  4. 用户响应
    • 接听:状态转为ACTIVE,建立双向通话。
    • 拒接:状态转为DISCONNECTED

流程图简化

接听
拒接
Modem上报来电
Ringer播放铃声
启动InCallActivity
显示RINGING界面
用户操作
ACTIVE状态
DISCONNECTED
3. MO与MT的核心区别
维度MO(主叫)MT(被叫)
触发起点用户主动拨号网络侧下发来电请求
关键状态DIALING(拨号中)RINGING(响铃中)
系统组件DialpadFragment触发IntentRIL/CallsManager检测来电状态
特殊处理紧急呼叫权限绕过铃声播放(Ringer
VoLTE角色主叫UE构造SIP INVITE被叫S-CSCF触发业务逻辑(如彩铃)
注意点
  • MO:用户拨号 → 权限检查 → Telecom处理 → 界面显示DIALING → 通话建立(ACTIVE)。
  • MT:网络下发来电 → 播放铃声 → 界面显示RINGING → 用户接听(ACTIVE)或拒接(DISCONNECTED)。
    本质差异在于触发源(用户主动 vs. 网络被动)和核心状态DIALING vs. RINGING)。理解两者区别对开发通话功能、优化用户体验及设计测试用例至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swift 6 学习笔记(二)The Basics

这篇笔记也是同步 Swift 6 官方教程中的第二篇 《The Basics》,这篇博客中的大部分内容在第一篇中已经涉及,这篇可以被认为是基础类型的的补充篇,多了很多说明信息。 官方教学文档 《The Basics》: Swift 提供了许多基本数据类型…

【PHP】BC Math 函数参考表

BC Math 函数参考表: 函数名描述语法bcadd两个任意精度数字的加法bcadd($num1, $num2, [scale])bcsub两个任意精度数字的减法bcsub($num1, $num2, [scale])bcmul两个任意精度数字乘法bcmul($num1, $num2, [scale])bcdiv两个任意精度数字除法bcdiv($num1, $num2, [scale])bcmod…

C# TAP异步编程(Task/async/await)总结

C#中有个很好用的东西,TAP异步编程(Task-based Asynchronous Pattern),是目前C#推荐的异步编程模型。它基于 System.Threading.Tasks.Task 和 async/await 关键字,旨在简化异步代码的编写、调试和维护。TAP 是现代 .NE…

达梦数据库(DM)用户名大小写处理规则

达梦数据库(DM)用户名大小写处理规则 达梦数据库对用户名的处理与PostgreSQL和Oracle有所不同,以下是相关说明: 一、基本规则 默认情况下:达梦数据库区分用户名大小写 创建的用户名会保留原始大小写格式连接时必须使用相同的大小写形式 …

黑马点评面试话术

文章目录 1.项目介绍2. 分布式登录功能2.1 讲讲登录的整个流程2.2 集群模式session下存储用户信息会有啥问题?2.3 为什么采用redis存储用户信息和验证码2.4 redis的存储格式怎么样的?2.5 为什么采用Hash结构存储用户信息2.6 为什么采用双拦截器&#xff…

MTK APEX测光系统中各变量具体的计算方式探究

目录 一、APEX测光系统介绍 二、MTK测光系统实例介绍 三、关于测光系统的一些疑问 一、APEX测光系统介绍 详细内容可以参考; AE(自动曝光)系统简介

K8S的基本概念

Kubernetes是一个开源的容器编排部署管理平台,用于管理云平台中多个主机上的容器化应用。Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新、维护的一种机制。 对应用开发者而言,可以把Kubernetes看成一个集群操作系统。Kubernetes…

NLP学习路线图(三十四): 命名实体识别(NER)

一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…

大三自学笔记:探索Hyperlane框架的心路历程

## Day 1:初识 Hyperlane 在 GitHub 上发现了 Hyperlane 这个 Rust HTTP 框架,立刻被它的性能数据吸引。官方文档写着: > "hyperlane 是一个高性能且轻量级的 Rust HTTP 框架,设计目标是简化现代 Web 服务的开发&#xff…

Java大厂面试真题:谢飞机的技术挑战

Java大厂面试真题:谢飞机的技术挑战 场景一:电商场景 面试官:在电商项目中,我们通常需要处理大量的并发请求。请谈谈你对JVM调优的理解。 谢飞机:嗯,JVM调优主要是为了提高程序的性能和稳定性。比如&…

【Docker管理工具】安装容器管理工具Oxker

【Docker管理工具】安装Oxker容器管理工具 一、Oxker介绍1.1 Oxker简介1.2 Oxker功能1.3 Docker介绍 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Oxker镜像五、安装Oxke…

产品成本分析怎么做?从0到1搭建全生命周期分析框架!

目录 一、为什么要做产品全生命周期成本分析? 1.资源再分配 2.动态成本校准 3.战略决策支持 二、产品成本分析思路 1.建立全生命周期成本追踪 2.联动分析关键指标 3.定位问题产品线 4.资源效率四象限分配 三、产品成本分析指标 1.分投入成本:…

机器学习与深度学习20-数学优化

目录 前文回顾1.梯度下降的基本原理2.什么是损失函数?3.随机梯度下降和小批量梯度下降4.什么是学习率5.优化算法中的收敛性6.常用的数学优化算法 前文回顾 上一篇文章链接:地址 1.梯度下降的基本原理 梯度下降(Gradient Descent&#xff0…

Photoshop 2025 性能配置全攻略:硬件选购与软件优化指南

一、硬件配置核心建议 根据Adobe官方要求及实测反馈,Photoshop 2025对硬件的需求侧重CPU、内存和存储,显卡需求相对宽松,但特定功能(如AI滤镜、3D渲染)需关注显卡性能。 硬件类别最低配置推荐配置(流畅运…

华为云Flexus+DeepSeek征文 | 华为云ModelArts Studio快速上手:DeepSeek-R1-0528商用服务的开通与使用

华为云FlexusDeepSeek征文 | 华为云ModelArts Studio快速上手:DeepSeek-R1-0528商用服务的开通与使用 引言一、ModelArts Studio平台介绍华为云ModelArts Studio简介ModelArts Studio主要特点 二、开通DeepSeek-R1-0528商用服务访问ModelArts Studio控制台DeepSeek-…

day53 神经网络调参指南

目录 一、引言 二、权重初始化:为何如此重要? (一)随机种子:确保实验的可重复性 (二)权重初始化的重要性 1. 神经网络的对称性问题 2. 避免梯度消失和梯度爆炸 (三&#xff0…

【大模型02---Megatron-LM】

文章目录 Megatron-LM数据并行模型并行张量并行流水线并行 3D并行 Megatron-LM Megatron是当前大模型训练时经常使用的一种分布式并行框架,它通过采用DP,TP,PP等来加速模型的训练,反正就是一个字,好。 大模型在训练的时候,显存占…

魔百和网络机顶盒CM211-1硬件解析

先来个正面照 背面照 核芯 无线网卡 支持WiFi与蓝牙 硬盘 正面内存与背面内存

Kratos 与Golang Cms的关系

Kratos 与 Golang CMS 的关系 Kratos 是 Bilibili 开源的一款轻量级 Go 语言微服务框架,专注于构建高性能、可扩展的后端服务。虽然它本身并不是一个完整的 CMS(内容管理系统),但它可以用于开发 CMS 系统的后端或 API 服务。 我们的目标是提供全面的微服务开发技术。基于…

在vue3+vite中给 Video视频 添加字幕

Video视频 添加字幕 方式一: 使用 track标签template标签中css样式修改方式二:直接读取.vtt文件方式一: 使用 track标签 参考1:https://blog.csdn.net/weixin_42321819/article/details/112442773 参考2:https://blog.csdn.net/foren_whb/article/details/80810552 template标…