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

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已标注弃用,但旧版本仍可用):

  1. 实现广播接收器:
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")
                }
            }
        }
    }
}
  1. 在清单文件中注册接收器:
<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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:27:33