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
相关产品推荐
相关产品推荐

