当前位置: 首页 > news >正文

MTK-Android13-Dialer 通话界面定制修改

定制通话界面

文章目录

  • 前言-需求
  • 一、参考资料
  • 二、修改文件-实现方案
    • 修改文件
    • 修改思路
    • 实现方案
      • isSupportedButton 方法去掉id 判断
      • onViewCreated 方法中去掉需要添加的UI组件
      • onInCallScreenDialpadVisibilityChange 方法屏蔽组件BUTTON_DIALPAD
      • setHold 方法屏蔽掉需要屏蔽的组件操作BUTTON_HOLD 逻辑
      • setAudioState 去除静音和免提相关功能业务
      • updateRecordStateUi 去除录音相关业务
  • 三、源码分析
    • InCallFragment 分析
    • ButtonController 源码分析
  • 总结


前言-需求

Android中打电话的应用是Dialer,部分商用的场景比如:电话亭、公司共用电话、校园共用电话场景是由一定的定制场景的。

具体需求如下:把通话界面的所有功能按钮全部去掉
在这里插入图片描述

一、参考资料

Android8.1 MTK 平台Dialer修改(通话常亮、按钮接听)
Android Dialer源码分析之IncallUI中SpeakerButton点击后显示音频选择器
IncallUI里面各个按键功能流程
Android Dialer源码分析之IncallUI中SpeakerButton点击后显示音频选择器

备注:

  • Dialer 源码分析比较少、定制比较少,可以借鉴下 针对自己的需求看看源码
  • 参考资料仅给一下思考,还是得根据自己AOSP 源码查看具体代码,根据架构、层次、业务进行修改!

二、修改文件-实现方案

修改文件

vendor/mediatek/proprietary/packages/apps/Dialer/java/com/android/incallui/incall/impl/InCallFragment.java

修改思路

打开通话界面进行电话时候,查看日志如下,找到对应的源码 InCallFragment
在这里插入图片描述
在这里插入图片描述

实现方案

InCallFragment 中屏蔽掉动态添加的组件和相关id 获取判断逻辑即可

isSupportedButton 方法去掉id 判断

 private static boolean isSupportedButton(@InCallButtonIds int id) {return//        id == InCallButtonIds.BUTTON_AUDIO//     || id == InCallButtonIds.BUTTON_MUTE//    || id == InCallButtonIds.BUTTON_DIALPAD// id == InCallButtonIds.BUTTON_HOLDid == InCallButtonIds.BUTTON_SWAP//     || id == InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO//     || id == InCallButtonIds.BUTTON_ADD_CALL|| id == InCallButtonIds.BUTTON_MERGE|| id == InCallButtonIds.BUTTON_MANAGE_VOICE_CONFERENCE|| id == InCallButtonIds.BUTTON_SWAP_SIM|| id == InCallButtonIds.BUTTON_UPGRADE_TO_RTT/// M: [Voice Record]//    || id == InCallButtonIds.BUTTON_SWITCH_VOICE_RECORD/// M: [Hang Up]|| id == InCallButtonIds.BUTTON_HANG_UP_ALL|| id == InCallButtonIds.BUTTON_HANG_UP_HOLD/// M: [ECT(blind)]|| id == InCallButtonIds.BUTTON_ECT|| id == InCallButtonIds.BUTTON_BLIND_ECT/// M: [One way video]|| id == InCallButtonIds.BUTTON_ONE_WAY_VIDEO/// M: ALPS03949921, add switch_to_secondary to enable and disable.|| id == InCallButtonIds.BUTTON_SWITCH_TO_SECONDARY;}

onViewCreated 方法中去掉需要添加的UI组件

@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle bundle) {LogUtil.i("InCallFragment.onViewCreated", null);super.onViewCreated(view, bundle);/// M: [Voice Record] Add for recording. @{initVoiceRecorderIcon(view);/// @}inCallScreenDelegate =FragmentUtils.getParent(this, InCallScreenDelegateFactory.class).newInCallScreenDelegate();Assert.isNotNull(inCallScreenDelegate);//  buttonControllers.add(new ButtonController.MuteButtonController(inCallButtonUiDelegate));//  buttonControllers.add(new ButtonController.SpeakerButtonController(inCallButtonUiDelegate));//  buttonControllers.add(new ButtonController.DialpadButtonController(inCallButtonUiDelegate));//  buttonControllers.add(new ButtonController.HoldButtonController(inCallButtonUiDelegate));//    buttonControllers.add(new ButtonController.AddCallButtonController(inCallButtonUiDelegate));buttonControllers.add(new ButtonController.SwapButtonController(inCallButtonUiDelegate));buttonControllers.add(new ButtonController.MergeButtonController(inCallButtonUiDelegate));buttonControllers.add(new ButtonController.SwapSimButtonController(inCallButtonUiDelegate));/*  buttonControllers.add(new ButtonController.UpgradeToVideoButtonController(inCallButtonUiDelegate));*/buttonControllers.add(new UpgradeToRttButtonController(inCallButtonUiDelegate));buttonControllers.add(new ButtonController.ManageConferenceButtonController(inCallScreenDelegate));buttonControllers.add(new ButtonController.SwitchToSecondaryButtonController(inCallScreenDelegate));/// M: [Voice Record] @{/*  buttonControllers.add(new ButtonController.SwitchVoiceRecordButtonController(inCallButtonUiDelegate));*//// @}/// M: [Hang Up] @{buttonControllers.add(new ButtonController.HangupAllButtonController(inCallScreenDelegate));buttonControllers.add(new ButtonController.HangupHoldButtonController(inCallScreenDelegate));/// @}/// M: [ECT(blind)] @{buttonControllers.add(new ButtonController.ECTButtonController(inCallButtonUiDelegate));buttonControllers.add(new ButtonController.BlindECTButtonController(inCallButtonUiDelegate));/// @}/// M: [One way video] @{buttonControllers.add(new ButtonController.UpgradeToOneWayVideoButtonController(inCallButtonUiDelegate));/// @}inCallScreenDelegate.onInCallScreenDelegateInit(this);inCallScreenDelegate.onInCallScreenReady();}

onInCallScreenDialpadVisibilityChange 方法屏蔽组件BUTTON_DIALPAD

 @Overridepublic void onInCallScreenDialpadVisibilityChange(boolean isShowing) {LogUtil.i("InCallFragment.onInCallScreenDialpadVisibilityChange", "isShowing: " + isShowing);// Take note that the dialpad button isShowing//  getButtonController(InCallButtonIds.BUTTON_DIALPAD).setChecked(isShowing);// This check is needed because there is a race condition where we attempt to update// ButtonGridFragment before it is ready, so we check whether it is ready first and once it is// ready, #onButtonGridCreated will mark the dialpad button as isShowing.if (inCallButtonGridFragment != null) {// Update the Android Button's state to isShowing.inCallButtonGridFragment.onInCallScreenDialpadVisibilityChange(isShowing);}Activity activity = getActivity();Window window = activity.getWindow();window.setNavigationBarColor(activity.getColor(isShowing ? android.R.color.background_dark : android.R.color.transparent));}

setHold 方法屏蔽掉需要屏蔽的组件操作BUTTON_HOLD 逻辑

  @Overridepublic void setHold(boolean value) {// getButtonController(InCallButtonIds.BUTTON_HOLD).setChecked(value);}

setAudioState 去除静音和免提相关功能业务

@Overridepublic void setAudioState(CallAudioState audioState) {/// M: do not show bluetooth device information. @{/// Google code: LogUtil.i("InCallFragment.setAudioState", "audioState: " + audioState);LogUtil.i("InCallFragment.setAudioState", "isMuted: " + audioState.isMuted() + ", route: "+ CallAudioState.audioRouteToString(audioState.getRoute()) + ", supportMask: "+ CallAudioState.audioRouteToString(audioState.getSupportedRouteMask()));/// @}/// M: ALPS05941240 AudioRouteSelectorDialogFragment would not dismiss when call/// audio state changed. @{AudioRouteSelectorDialogFragment audioRouteSelectorDialog =(AudioRouteSelectorDialogFragment) this.getChildFragmentManager().findFragmentByTag(TAG_AUDIOROUTE_SELECTOR_FRAGMENT);if (audioRouteSelectorDialog != null) {audioRouteSelectorDialog.dismissAllowingStateLoss();audioRouteSelectorDialog = null;}/// @}/*  ((SpeakerButtonController) getButtonController(InCallButtonIds.BUTTON_AUDIO)).setAudioState(audioState);*///   getButtonController(InCallButtonIds.BUTTON_MUTE).setChecked(audioState.isMuted());}

updateRecordStateUi 去除录音相关业务

 /*** M: [Voice Record] updateRecordStateUi* @param isRecording*/@Overridepublic void updateRecordStateUi(boolean isRecording) {LogUtil.d("InCallFragment.updateRecordStateUi", "[updateRecordStateUi]... " + isRecording);DialerCall ringCall = CallList.getInstance().getIncomingCall();if (isRecording && (ringCall == null)) {updateVoiceRecordIcon(true);} else {updateVoiceRecordIcon(false);}//   getButtonController(InCallButtonIds.BUTTON_SWITCH_VOICE_RECORD).setChecked(isRecording);}

三、源码分析

InCallFragment 分析

看源码 如下:

/** Fragment that shows UI for an ongoing voice call. */
public class InCallFragment extends Fragmentimplements InCallScreen,InCallButtonUi,OnClickListener,AudioRouteSelectorPresenter,OnButtonGridCreatedListener {....}

看类定义,它本质上就是一个通话界面的UI,直接集成了Fragment 组件。所以它就是一个显示UI组件并具备生命周期

ButtonController 源码分析

看类定义,原来它就是一个接口,管理Button用的。

/** Manages a single button. */
interface ButtonController {
............
}

那为什么会分析到这里,一方面它从直观上来看,就是管理Button的,再具体看看源码:
在这里插入图片描述

  • 定义了所有的功能Button
  • 对每个自定义功能Button 描述和定义,都有相关的String/Id

所以,当我们找到这里时候就提供了解决需求的思路,一步一步去解决实际需求和阅读相关源码。

总结

  • 这个需求其实很简单的,通过阅读源码并分析源码能够快速实现需求
  • 这里面比较坑的是,其实部分按钮咋一看和实际ID 很难对上,本身也不熟悉情况下导致修改错误,建议一个一个或者再无编译报错情况下一个一个验证。
  • 初识Dialer 界面源码和部分业务逻辑,实际项目中其实还涉及到在原生APP基础上定制这个UI界面,这样就需要了解这个源码并针对性修改了。
http://www.dtcms.com/a/415162.html

相关文章:

  • 化妆品电子商务网站开发流程描述中山网站建设推荐
  • 宿州移动网站建设广州模板网站
  • 旅游景区网站建设哈尔滨发布信息的网站
  • RVC WebUI(Retrieval-based-Voice-Conversion-WebUI)配置
  • 在线制作简历网站网页结构布局
  • 建网站要备案东莞网站制作品牌祥奔科技
  • 棋盘覆盖问题
  • 大邑网站建设百合居装饰公司官网
  • C++基础(3)-类的6个默认成员函数
  • 做营销型网站需要注意哪些点开发小程序费用
  • AI“点亮”萤火虫:边缘机器学习让微光成像走进4K时代
  • 【手撕机器学习 02】手撕算法的基石:精通NumPy与Pandas向量化思维
  • 一种好用开发的轻量级 Markdown 编辑器
  • 网站用户管理系统徐州市城乡建设局网站
  • 花店网站首页模版帝国cms使用教程
  • React-router v6学生管理系统笔记
  • 手写签名太麻烦?智能签名生成器免费实测 智能签名生成器、智能签名生成器使用、免费电子签名工具、Windows 电子签名软件、办公效率工具
  • 建设银行六安市分行网站hreflang wordpress
  • N8N Workflow Collection - 专业级自动化工作流库
  • 有没有专业做特产的网站小企业如何建网站
  • Android 6.0+ 动态权限请求模块,这个模块会包含 权限检查、请求、结果处理 等核心功能,并且支持 单个 / 多个权限请求、权限拒绝后的引导
  • Android -自定义Binding Adapter实战应用
  • 网站优化提升速度网站建设权利义务
  • 【复现】一种基于价格弹性矩阵的居民峰谷分时电价激励策略【需求响应】
  • 【怎么复制cmd命令行里面的文字输出和报错】
  • Oracle体系结构-RECO详解
  • 2025.9.27总结
  • 做网站怎么跟客户谈话搜狗优化好的网站
  • 乐清网站推广公司怎样取消2345网址导航
  • AI时代大数据分布的深入洞察与应用