Android来电响铃时编程获取来电号码方案咨询
Android来电响铃时实时获取来电号码的解决方案(替代已弃用的EXTRA_INCOMING_NUMBER)
一、申请必要权限
首先需要在清单文件中声明危险权限,并在运行时动态申请:
<!-- 清单文件中添加权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CALL_LOG" />
在代码中动态请求权限(以Kotlin为例):
// 检查并请求权限 val permissions = arrayOf(Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CALL_LOG) if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED ) { registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { results -> // 处理权限申请结果 }.launch(permissions) }
二、Android 12+(API 31及以上):使用TelephonyCallback监听
Android 12开始弃用了广播方式获取来电号码,官方推荐使用TelephonyCallback.IncomingCallListener实现实时监听:
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager val mainExecutor = ContextCompat.getMainExecutor(this) val incomingCallCallback = object : TelephonyCallback(), TelephonyCallback.IncomingCallListener { override fun onIncomingCall(callDetails: TelephonyCallback.CallDetails) { // 从CallDetails中提取来电号码 val phoneNumber = callDetails.handle?.schemeSpecificPart if (!phoneNumber.isNullOrEmpty()) { // 实时处理来电号码,比如弹窗显示、日志记录等 Log.d("IncomingCall", "当前来电号码:$phoneNumber") } } } // 权限验证通过后注册回调 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED ) { telephonyManager.registerTelephonyCallback(mainExecutor, incomingCallCallback) } // 在页面销毁时注销回调,避免内存泄漏 override fun onDestroy() { super.onDestroy() telephonyManager.unregisterTelephonyCallback(incomingCallCallback) }
三、Android 11及以下:兼容旧的广播方式
对于Android 11及以下版本,仍然可以通过监听ACTION_PHONE_STATE_CHANGED广播获取来电号码(虽然EXTRA_INCOMING_NUMBER已标注弃用,但旧版本仍可用):
- 实现广播接收器:
class IncomingCallReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { intent?.takeIf { it.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED }?.let { val state = it.getStringExtra(TelephonyManager.EXTRA_STATE) if (state == TelephonyManager.EXTRA_STATE_RINGING) { val phoneNumber = it.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) phoneNumber?.let { number -> Log.d("IncomingCall", "当前来电号码:$number") } } } } }
- 在清单文件中注册接收器:
<receiver android:name=".IncomingCallReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver>
关键注意事项
- Android 12+必须使用
TelephonyCallback,广播方式不再提供来电号码字段。 - 所有版本都必须申请
READ_PHONE_STATE和READ_CALL_LOG权限,否则无法获取号码。 - 注册的回调/接收器要及时注销,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user20273569
相关产品推荐
相关产品推荐

