APP活跃通话时接GSM电话,Telecom Connection的onHold/onUnhold未触发
问题描述
我已在应用中集成Telecom子系统,并为Connection设置了CAPABILITY_SUPPORT_HOLD等能力。当应用处于活跃通话状态时,若收到GSM来电并接听,TelecomConnection类的onHold和onUnhold回调函数未被触发,反而onDisconnect回调被触发。请问我的实现是否存在遗漏?
相关代码
VoiceConnectionService 实现
class VoiceConnectionService : ConnectionService() { var activeConnection: Connection? = null override fun onCreateIncomingConnection( connectionManagerPhoneAccount: PhoneAccountHandle, request: ConnectionRequest ): Connection? { val incomingCallConnection = createConnection(request) incomingCallConnection?.setRinging() return incomingCallConnection } private fun createConnection(request: ConnectionRequest): Connection? { activeConnection = TelecomConnection() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { (activeConnection as TelecomTwilioConnection).connectionProperties = Connection.PROPERTY_SELF_MANAGED } (activeConnection as TelecomTwilioConnection).connectionCapabilities = Connection.CAPABILITY_MUTE (activeConnection as TelecomTwilioConnection).connectionCapabilities = Connection.CAPABILITY_SUPPORT_HOLD return activeConnection } }
TelecomConnection 实现
class TelecomConnection : Connection() { override fun onHold() { } override fun onUnhold() { } }
Manifest 中 Service 配置
<service android:name=".twilio.telecom.VoiceConnectionService" android:label="VoiceConnectionService" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" android:exported="false"> <intent-filter> <action android:name="android.telecom.ConnectionService" /> </intent-filter> </service>
问题分析与修复建议
你的实现存在几个关键问题,导致通话切换时触发onDisconnect而非预期的onHold/onUnhold:
- 连接能力赋值错误
connectionCapabilities是位掩码属性,需用|=操作符累加能力,直接赋值会覆盖之前的配置。你当前代码先设置CAPABILITY_MUTE,随后被CAPABILITY_SUPPORT_HOLD覆盖,最终仅HOLD能力生效,且类型转换存在错误——实例化的是TelecomConnection,却强制转为TelecomTwilioConnection,会直接抛出ClassCastException,导致连接创建失败。
正确写法:
// 修正能力赋值与类型问题 private fun createConnection(request: ConnectionRequest): Connection? { val connection = TelecomConnection() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { connection.connectionProperties = Connection.PROPERTY_SELF_MANAGED } connection.connectionCapabilities = Connection.CAPABILITY_MUTE or Connection.CAPABILITY_SUPPORT_HOLD activeConnection = connection return connection }
- 未注册PhoneAccount到Telecom系统
Telecom需要识别你的应用通话账户,才能将其纳入系统通话管理流程。需在应用初始化时通过TelecomManager注册:
val telecomManager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager val packageName = packageName val accountHandle = PhoneAccountHandle(ComponentName(packageName, VoiceConnectionService::class.java.name), "custom_account_id") val phoneAccount = PhoneAccount.Builder(accountHandle, "应用通话账户") .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER or PhoneAccount.CAPABILITY_SUPPORT_HOLD) .build() telecomManager.registerPhoneAccount(phoneAccount)
- 未正确同步通话状态到Telecom
当系统触发保持/恢复操作时,你的Connection需要主动向Telecom确认状态变更:
class TelecomConnection : Connection() { override fun onHold() { // 执行你的通话SDK保持逻辑 setOnHold() // 通知Telecom已进入保持状态 } override fun onUnhold() { // 执行你的通话SDK恢复逻辑 setActive() // 通知Telecom已恢复活跃状态 } // 通话激活时调用此方法 fun markAsActive() { setActive() } }
- 权限与配置检查
确保已申请必要权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <!-- Android 12及以下需添加 --> <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
若需跨应用交互,可将service的android:exported设为true,注意权限安全。
内容的提问来源于stack exchange,提问作者Jitendra Reddy
相关产品推荐
相关产品推荐

