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

Android 13下如何获取外呼电话被对方接听的事件?

解决方案:Android 13 捕获外呼电话接听事件

针对Android 13下无法通过TelephonyCallback.CallStateListener捕获外呼接听事件的问题,推荐使用**Android Telecom框架的Call.Callback**来监听更精细的通话状态,这是当前非系统应用实现该需求的可靠方案。

一、核心思路:利用Telecom的精细通话状态

Android Telecom框架的Call类提供了比TelephonyManager更细分的状态,其中:

  • Call.STATE_DIALING:外呼发起,正在拨号
  • Call.STATE_RINGING:对方电话正在响铃
  • Call.STATE_ACTIVE:对方已接听,通话正式建立
  • Call.STATE_DISCONNECTED:通话结束

通过监听这些状态变化,就能精准捕获到外呼被接听的时刻。

二、实现步骤

1. 申请必要权限

在AndroidManifest.xml中声明权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Android 13中该权限属于危险权限,需在运行时动态申请。

2. 注册Call.Callback监听

获取TelecomManager实例并注册回调:

val telecomManager = getSystemService(TELECOM_SERVICE) as TelecomManager

val callCallback = object : Call.Callback() {
    override fun onCallStateChanged(call: Call, state: Int) {
        super.onCallStateChanged(call, state)
        when (state) {
            Call.STATE_DIALING -> {
                // 外呼拨号中
            }
            Call.STATE_RINGING -> {
                // 对方正在响铃
            }
            Call.STATE_ACTIVE -> {
                // 对方已接听,触发录音逻辑
            }
            Call.STATE_DISCONNECTED -> {
                // 通话结束,停止录音
            }
        }
    }
}

telecomManager.registerCallback(callCallback, null)

3. 注意事项

  • 确保应用已获得READ_PHONE_STATE权限,否则无法注册回调或获取通话状态。
  • 在应用生命周期结束时(如onDestroy)调用telecomManager.unregisterCallback(callCallback),避免内存泄漏。

三、备选方案:监听音频路由变化(可靠性稍弱)

如果Telecom方案因限制无法使用,可通过AudioManager监听音频路由切换作为补充:
外呼被接听时,系统通常会将音频路由从默认扬声器切换到听筒(或蓝牙设备),结合Telephony的CALL_STATE_OFFHOOK状态,可间接判断通话已接通:

val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager

val audioDeviceCallback = object : AudioManager.AudioDeviceCallback() {
    override fun onAudioDevicesAdded(addedDevices: MutableList<AudioDeviceInfo>?) {
        super.onAudioDevicesAdded(addedDevices)
        val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
        if (telephonyManager.callState == TelephonyManager.CALL_STATE_OFFHOOK) {
            addedDevices?.forEach { device ->
                if (device.type == AudioDeviceInfo.TYPE_EARPIECE) {
                    // 大概率是通话已接通
                }
            }
        }
    }
}

audioManager.registerAudioDeviceCallback(audioDeviceCallback, null)

该方法存在误判可能(如用户手动切换音频设备),建议仅作为Telecom方案的补充。


内容的提问来源于stack exchange,提问作者Haru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:10:18