You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 连接能力赋值错误
    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
}
  1. 未注册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)
  1. 未正确同步通话状态到Telecom
    当系统触发保持/恢复操作时,你的Connection需要主动向Telecom确认状态变更:
class TelecomConnection : Connection() {

    override fun onHold() {
        // 执行你的通话SDK保持逻辑
        setOnHold() // 通知Telecom已进入保持状态
    }

    override fun onUnhold() {
        // 执行你的通话SDK恢复逻辑
        setActive() // 通知Telecom已恢复活跃状态
    }

    // 通话激活时调用此方法
    fun markAsActive() {
        setActive()
    }
}
  1. 权限与配置检查
    确保已申请必要权限:
<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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:10:33