如何在使用ConnectionService的addNewIncomingCall时显示自定义UI?
我正在实现ConnectionService,调用addNewIncomingCall时会弹出系统默认的来电接听/拒接UI。
调用来电的代码示例:
var handle = account.accountHandle val extras = Bundle() extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle) val manager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager manager.addNewIncomingCall(handle, extras)
注册账号的代码:
fun registerConnectionService() { val manager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager val connectionServiceId = getConnectionServiceId() val componentName = ComponentName(applicationContext, PhoneConnectionService::class.java) val phoneAccountHandle = PhoneAccountHandle(componentName, connectionServiceId) val builder = PhoneAccount.builder( phoneAccountHandle, this.resources.getText(R.string.app_name) ) val uri = Uri.fromParts("tel", "123456789", null) builder.setSubscriptionAddress(uri) builder.setAddress(uri) builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER) builder.setShortDescription("Short description") phoneAccount = builder.build() manager.registerPhoneAccount(phoneAccount) }
我知道需要设置PhoneAccount.CAPABILITY_SELF_MANAGED来启用自定义UI:
builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED)
接收来电的ConnectionService代码:
@Override public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) { final CallConnection connection = new CallConnection(this); Bundle extras = new Bundle(); connection.setAddress(request.getAddress(), PRESENTATION_ALLOWED); connection.setVideoState(VideoProfile.STATE_AUDIO_ONLY); connection.setExtras(extras); connection.setConnectionCapabilities(Connection.CAPABILITY_SUPPORT_DEFLECT); connection.setRingbackRequested(true); connection.setRinging(); return connection; }
但继承自Connection的CallConnection类中的onShowIncomingCallUi方法始终没有被调用,请问该如何解决?
解决方案
要让onShowIncomingCallUi触发并正常使用自定义来电UI,需逐一检查并完成以下配置:
修正PhoneAccount的能力配置
不要直接替换掉CAPABILITY_CALL_PROVIDER,需同时保留两种能力(如果你的应用仍需作为通话提供商):builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED or PhoneAccount.CAPABILITY_CALL_PROVIDER)CAPABILITY_SELF_MANAGED的核心作用是告知系统:该应用将自行处理来电UI,无需弹出系统默认界面。完善ConnectionService的Manifest声明
在AndroidManifest.xml中注册服务时,必须绑定指定权限并添加正确的Intent Filter:<service android:name=".PhoneConnectionService" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"> <intent-filter> <action android:name="android.telecom.ConnectionService" /> </intent-filter> </service>确保CallConnection正确重写方法
检查你的CallConnection类是否正确实现onShowIncomingCallUi,并在方法内启动自定义来电UI的Activity:public class CallConnection extends Connection { public CallConnection(Context context) { super(context); } @Override public void onShowIncomingCallUi() { // 启动自定义来电UI页面 Intent intent = new Intent(getContext(), CustomIncomingCallActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); getContext().startActivity(intent); } }检查必要权限
根据系统版本,确保应用已获取对应权限:- Android 10及以上:
READ_PHONE_STATE、ANSWER_PHONE_CALLS - Android 13及以上:额外需要
POST_NOTIFICATIONS(来电通知是触发UI的前提)
部分定制ROM可能需要手动在系统设置中允许应用作为默认通话应用。
- Android 10及以上:
优化来电调用时的参数
调用addNewIncomingCall时,避免传递强制使用系统UI的参数,可补充自定义参数供后续UI使用:val extras = Bundle().apply { putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle) // 可添加自定义键值对,传递来电相关信息 }
内容的提问来源于stack exchange,提问作者Mohammad Taqi

