• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android7.0 Phone应用源码分析(三) phone拒接流程分析,android7.0拒接

Android7.0 Phone应用源码分析(三) phone拒接流程分析,android7.0拒接

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了Android7.0 Phone应用源码分析(三) phone拒接流程分析,android7.0拒接等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android7.0 Phone应用源码分析(三) phone拒接流程分析,android7.0拒接


接上篇博文:Android7.0 Phone应用源码分析(二) phone来电流程分析

今天我们再来分析下Android7.0 的phone的拒接流程

incoming

下面先来看一下拒接电话流程时序图

步骤1:滑动按钮到拒接图标,会调用到AnswerFragment的onDecline方法

com.android.incallui.AnswerFragment
public void onDecline(Context context) {
        getPresenter().onDecline(context);
 }

最后是调用到AnswerPresenteronDecline方法

com.android.incallui.AnswerPresenter
 public void onDecline(Context context) {
        Log.d(this, "onDecline " + mCallId);
        if (mCall.getSessionModificationState()
                == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
            InCallPresenter.getInstance().declineUpgradeRequest(context);
        } else {
            TelecomAdapter.getInstance().rejectCall(mCall.getId(), false, null);
        }
 }

步骤2:进入TelecomAdapter的rejectCall方法

com.android.incallui.TelecomAdapter
void rejectCall(String callId, boolean rejectWithMessage, String message) {
        android.telecom.Call call = getTelecomCallById(callId);
        if (call != null) {
            call.reject(rejectWithMessage, message);
        } else {
            Log.e(this, "error rejectCall, call not in call list: " + callId);
        }
}

TelecomAdapter是incallui与telecom通信的代理类,这里通过callid取出对应的Call对象(android.telecom.Call)

步骤3:调用到framework里Call的reject方法

android.telecom.Call
public void reject(boolean rejectWithMessage, String textMessage) {
        mInCallAdapter.rejectCall(mTelecomCallId, rejectWithMessage, textMessage);
 }

这里mInCallAdapter是android.telecom.InCallAdapter类,是在Call对象创建的时候由外部传入的参数

在telecom绑定InCallService服务的时候,会传递一个AIDL接口对象,InCallService会生成InCallAdapter对象来保存这个接口对象

步骤4:InCallAdapter的rejectCall方法

android.telecom.InCallAdapter
public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
        try {
            mAdapter.rejectCall(callId, rejectWithMessage, textMessage);
        } catch (RemoteException e) {
        }
 }

mAdapter就是incallui与telecom通信的AIDL接口

步骤5:跨进程调用进入telecom进程,该AIDL接口具体实现类是InCallAdapter,虽然类名一样但是不同的包名,这里需要注意一下

com.android.server.telecom.InCallAdapter
 public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
        try {
            Log.startSession("ICA.rC", mOwnerComponentName);
            long token = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    Log.d(this, "rejectCall(%s,%b,%s)", callId, rejectWithMessage, textMessage);
                    Call call = mCallIdMapper.getCall(callId);
                    if (call != null) {
                        mCallsManager.rejectCall(call, rejectWithMessage, textMessage);
                    } else {
                        Log.w(this, "setRingback, unknown call id: %s", callId);
                    }
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        } finally {
            Log.endSession();
        }
 }

这里同样是根据callid取出对应Call(com.android.server.telecom.Call),最后调用CallsManager的rejectCall方法传入call

步骤6:CallsManager的rejectCall方法

com.android.server.telecom.CallsManager
public void rejectCall(Call call, boolean rejectWithMessage, String textMessage) {
        if (!mCalls.contains(call)) {
            Log.i(this, "Request to reject a non-existent call %s", call);
        } else {
            for (CallsManagerListener listener : mListeners) {
                listener.onIncomingCallRejected(call, rejectWithMessage, textMessage);
            }
            call.reject(rejectWithMessage, textMessage);
        }
 }

这里先通知观察者来电拒接事件,比如CallAudioManager对该事件感兴趣,它的处理是停止播放来电铃声和来电等待声

com.android.server.telecom.CallAudioManager
 public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String message) {
        maybeStopRingingAndCallWaitingForAnsweredOrRejectedCall(call);
}
private void maybeStopRingingAndCallWaitingForAnsweredOrRejectedCall(Call call) {
        // Check to see if the call being answered/rejected is the only ringing call, since this
        // will be called before the connection service acknowledges the state change.
        if (mRingingCalls.size() == 0 ||
                (mRingingCalls.size() == 1 && call == mRingingCalls.iterator().next())) {
            mRinger.stopRinging();
            mRinger.stopCallWaiting();
        }
 }

最后再调用前面传进来的call对象的reject方法

步骤7:Call的reject方法

com.android.server.telecom.Call
public void reject(boolean rejectWithMessage, String textMessage) {
        Preconditions.checkNotNull(mConnectionService);

        // Check to verify that the call is still in the ringing state. A call can change states
        // between the time the user hits 'reject' and Telecomm receives the command.
        if (isRinging("reject")) {
            // Ensure video state history tracks video state at time of rejection.
            mVideoStateHistory |= mVideoState;

            mConnectionService.reject(this, rejectWithMessage, textMessage);
            Log.event(this, Log.Events.REQUEST_REJECT);
        }
}

这里的mConnectionService是ConnectionServiceWrapper类,是telecom与telephony通信的代理类

步骤8:ConnectionServiceWrapper的reject方法

com.android.server.telecom.ConnectionServiceWrapper
void reject(Call call, boolean rejectWithMessage, String message) {
        final String callId = mCallIdMapper.getCallId(call);
        if (callId !=



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android7.0 Phone应用源码分析(三) phone拒接流程分析,android7.0拒接

相关文章

  • 2017-05-26抽取的BaseFragment和LoadingPage,basefragment
  • 2017-05-26ListView和Adapter的配合使用以及Adapter的重写,listviewadapter
  • 2017-05-26Android学习笔记-EditText(输入框)(一),android-edittext
  • 2017-05-26JSON解析,json在线解析
  • 2017-05-26Android仿QQ界面,android仿界面
  • 2017-05-26Android--activity切换时的动画,android--activity
  • 2017-05-26Android特效专辑(九)——仿微信雷达搜索好友特效,逻辑清晰实现简单
  • 2017-05-26仿拉手团购App8-- 更多模块,拉手团购app8--模块
  • 2017-05-26一个现代化的JSON库Moshi针对Android和Java,jsonandroid
  • 2017-05-26android浏览器 源码共享,android浏览器源码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • ListView和Adapter的配合使用以及Adapter的重写,listviewadapter
    • 将Android系统源码导入Android studio的方法,androidstudio
    • 关于安卓APP的启动界面,安卓APP启动界面
    • 使用Android-Debug-Database 在浏览器中查看App的数据库,清科zdatabase数据库
    • android实现无限轮播,android实现轮播
    • Android安全专项之Xposed劫持用户名密码实践
    • 3.5 监听EditText的内容变化
    • Android的Kotlin秘方(I):OnGlobalLayoutListener,
    • JRebel for Android 1.0发布!,jrebelandroid
    • 安卓中Paint类和Canvas类的方法汇总,安卓中canvas

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有