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

Android12下TelephonyManager的listen()废弃后如何监听CALL_STATE_RINGING通话状态

安卓通话状态监听正确实现方案(兼容全版本)

前置准备:权限配置

首先在AndroidManifest.xml中添加必要权限:

<!-- 读取电话状态权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

注意:Android 6.0(API 23)及以上版本需要先动态申请该危险权限,用户授权通过后再执行监听注册逻辑,否则会触发权限异常。

核心实现代码

注意事项

所有监听回调实例必须声明为类成员变量,避免被GC回收导致无法收到回调。

成员变量定义

// 兼容API 31以下的监听实例
private lateinit var oldPhoneStateListener: PhoneStateListener
// 兼容API 31及以上的监听实例
@RequiresApi(Build.VERSION_CODES.S)
private lateinit var telephonyCallback: MyPhoneStateListener
// 电话服务实例
private lateinit var telephonyManager: TelephonyManager

自定义API 31+回调类

@RequiresApi(Build.VERSION_CODES.S)
class MyPhoneStateListener(private val onCallStateChange: (Int) -> Unit) : TelephonyCallback(), TelephonyCallback.CallStateListener {
    override fun onCallStateChanged(state: Int) {
        onCallStateChange(state)
    }
}

注册监听逻辑

前台使用推荐在onStart生命周期中注册:

override fun onStart() {
    super.onStart()
    // 权限校验
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
        // 此处自行实现权限申请逻辑,权限通过后再执行后续注册逻辑
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 1001)
        return
    }

    telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        telephonyCallback = MyPhoneStateListener { state ->
            when (state) {
                TelephonyManager.CALL_STATE_RINGING -> {
                    // 来电响铃逻辑
                    transcribingAudioConsumer.stopTranscription(null)
                }
                TelephonyManager.CALL_STATE_OFFHOOK -> {
                    // 通话中逻辑
                }
                TelephonyManager.CALL_STATE_IDLE -> {
                    // 通话空闲逻辑
                }
            }
        }
        // 注册回调,mainExecutor保证回调在主线程执行
        telephonyManager.registerTelephonyCallback(mainExecutor, telephonyCallback)
    } else {
        oldPhoneStateListener = object : PhoneStateListener() {
            override fun onCallStateChanged(state: Int, phoneNumber: String?) {
                super.onCallStateChanged(state, phoneNumber)
                when (state) {
                    TelephonyManager.CALL_STATE_RINGING -> {
                        transcribingAudioConsumer.stopTranscription(null)
                    }
                }
            }
        }
        // 旧版本用listen方法注册
        telephonyManager.listen(oldPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
    }
}

取消监听逻辑

前台使用推荐在onStop生命周期中取消,避免内存泄漏:

override fun onStop() {
    super.onStop()
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
        return
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        telephonyManager.unregisterTelephonyCallback(telephonyCallback)
    } else {
        telephonyManager.listen(oldPhoneStateListener, PhoneStateListener.LISTEN_NONE)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:15:03