Android获取来电信息实现方案(适配API 31及前后版本)
Android API 31 前后来电信息获取适配方案
API 31(Android 12)以下版本实现
在API 31之前,BroadcastReceiver是监听来电状态的常规方案,步骤如下:
申请权限
- 清单文件中声明权限:
<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) }
- 清单文件中声明权限:
动态注册广播接收器
注意不要用静态注册(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监听来电:
申请权限
- 清单文件声明:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- API 33+ 需要通知权限才能处理来电相关逻辑 --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> - 动态申请上述权限(逻辑同API 31以下的权限申请)
- 清单文件声明:
注册来电监听器
使用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
相关产品推荐
相关产品推荐

