Android使用ConnectionService上报呼出时如何隐藏系统原生通话界面?
可行实现方案
方案1:使用Self-Managed ConnectionService(最优解,兼容Android 8.0+)
这是官方支持的标准实现方式,完全符合你的需求:
- Self-Managed模式的设计目的就是让应用自行管理通话UI,系统不会主动弹出原生通话界面
- 通话状态仍然受Telecom框架统一管理,所以当有GSM运营商来电时,系统仍然能检测到你当前有活跃通话,自动向主叫返回忙线状态
实现步骤:
- 在AndroidManifest中添加权限声明:
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
- 注册PhoneAccount时,将原有的
CAPABILITY_CALL_PROVIDER替换为CAPABILITY_SELF_MANAGED标志:
PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, "你的通话服务名称") .setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED) .setShortDescription("VOIP通话服务"); telecomManager.registerPhoneAccount(builder.build());
- 原有上报通话的代码基本不需要改动,系统不会再弹出原生通话界面,你只需要正常维护通话状态上报给Telecom框架即可。
方案2:低版本兼容方案(适配Android 8.0以下)
如果你的应用需要兼容Android 8.0以下版本,可以用非正规的兼容方案规避系统界面弹出:
- 调用
placeCall之后立刻发送关闭系统弹窗的广播,关闭刚弹出的原生通话界面:
voipUtilties.telecomManager.placeCall(uri, extras); // 新增以下代码 Intent closeDialogIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); Application.context.sendBroadcast(closeDialogIntent);
- 注意:该方案兼容性有限,部分高版本定制系统可能限制该广播的权限,不保证100%生效。
方案3:界面覆盖方案
如果上述方案都不符合你的场景,可以在呼出后立刻跳转到你自己应用的任意Activity,设置Activity的launchMode为singleTask,并且添加Intent.FLAG_ACTIVITY_NEW_TASK标志,主动将系统原生通话界面压到后台,对用户不可见。
内容的提问来源于stack exchange,提问作者Bilal Şimşek
相关产品推荐
相关产品推荐

