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

Android获取来电信息实现方案(适配API 31及前后版本)

Android API 31 前后来电信息获取适配方案

API 31(Android 12)以下版本实现

在API 31之前,BroadcastReceiver是监听来电状态的常规方案,步骤如下:

  1. 申请权限

    • 清单文件中声明权限:
      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      
    • 动态申请权限(Android 6.0+):
      if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
          ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), 1001)
      }
      
  2. 动态注册广播接收器
    注意不要用静态注册(API 26+后台广播限制),在Activity/Service中动态注册:

    private val phoneStateReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val state = intent?.getStringExtra(TelephonyManager.EXTRA_STATE)
            when (state) {
                TelephonyManager.EXTRA_STATE_RINGING -> {
                    val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
                    // 处理来电号码
                }
                TelephonyManager.EXTRA_STATE_OFFHOOK -> {
                    // 电话接通逻辑
                }
                TelephonyManager.EXTRA_STATE_IDLE -> {
                    // 电话挂断逻辑
                }
            }
        }
    }
    
    // 在onResume中注册
    override fun onResume() {
        super.onResume()
        IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED).apply {
            registerReceiver(phoneStateReceiver, this)
        }
    }
    
    // 在onPause中注销
    override fun onPause() {
        super.onPause()
        unregisterReceiver(phoneStateReceiver)
    }
    

API 31(Android 12)及以上版本实现

API 31开始,ACTION_PHONE_STATE_CHANGED广播不再发送给后台应用,官方推荐使用TelecomManager的addIncomingCallListener监听来电:

  1. 申请权限

    • 清单文件声明:
      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      <!-- API 33+ 需要通知权限才能处理来电相关逻辑 -->
      <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
      
    • 动态申请上述权限(逻辑同API 31以下的权限申请)
  2. 注册来电监听器
    使用TelecomManager注册IncomingCallListener,示例代码:

    private lateinit var telecomManager: TelecomManager
    private val incomingCallListener = object : TelecomManager.IncomingCallListener() {
        override fun onIncomingCall(callDetails: TelecomManager.CallDetails) {
            val incomingNumber = callDetails.handle?.schemeSpecificPart
            // 处理来电号码,callDetails还包含来电状态、通话类型等信息
        }
    
        override fun onCallStateChanged(callDetails: TelecomManager.CallDetails, state: Int) {
            // 监听通话状态变化
            when (state) {
                TelecomManager.CALL_STATE_RINGING -> {}
                TelecomManager.CALL_STATE_ACTIVE -> {}
                TelecomManager.CALL_STATE_DISCONNECTED -> {}
            }
        }
    }
    
    // 在onCreate中初始化并注册
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        telecomManager = getSystemService(TelecomManager::class.java)
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.addIncomingCallListener(mainExecutor, incomingCallListener)
        }
    }
    
    // 在onDestroy中注销监听器
    override fun onDestroy() {
        super.onDestroy()
        telecomManager.removeIncomingCallListener(incomingCallListener)
    }
    

关于ConnectionService的说明

ConnectionService是用于自定义通话界面、管理通话连接的组件,并非监听来电状态的工具,所以无法获取来电信息是正常的,改用上面的IncomingCallListener即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:20:06