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

双卡手机如何获取指定SIM卡的当前来电iccId并过滤来电?

解决双卡手机指定SIM卡来电拦截的正确方案

你当前通过延迟查询通话记录获取PHONE_ACCOUNT_ID的方式不可靠,因为通话记录的写入存在延迟,且容易拿到历史通话数据。要直接获取当前来电对应的SIM卡信息,推荐使用PhoneStateListener替代广播接收者,API 24及以上版本的onCallStateChanged重载方法可以直接拿到当前通话的PhoneAccountHandle,从而准确识别所属SIM卡。

具体实现步骤

1. 权限申请

确保在AndroidManifest.xml中声明必要权限,并在运行时申请动态权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" /> <!-- 如需处理通话记录时添加 -->

2. 注册PhoneStateListener监听来电

放弃ACTION_PHONE_STATE_CHANGED广播,改用TelephonyManager注册监听:

class CallStateMonitor(private val context: Context) {
    private val telephonyManager = context.getSystemService(TelephonyManager::class.java)
    private val targetPhoneAccountId = "你的目标SIM卡PhoneAccountId" // 提前获取并保存

    private val phoneStateListener = object : PhoneStateListener(Looper.getMainLooper()) {
        override fun onCallStateChanged(state: Int, phoneNumber: String?, account: PhoneAccountHandle?) {
            super.onCallStateChanged(state, phoneNumber, account)
            
            when (state) {
                TelephonyManager.CALL_STATE_RINGING -> {
                    // 当前是来电状态
                    phoneNumber?.let { number ->
                        account?.let { phoneAccount ->
                            // 对比当前来电的PhoneAccountId和目标ID
                            if (phoneAccount.id == targetPhoneAccountId) {
                                // 处理指定SIM卡的来电
                                handleTargetSimCall(context, number, state)
                            }
                        }
                    }
                }
                TelephonyManager.CALL_STATE_OFFHOOK -> {
                    // 通话接通,按需处理
                }
                TelephonyManager.CALL_STATE_IDLE -> {
                    // 通话结束,按需处理
                }
            }
        }
    }

    // 开始监听
    fun startListening() {
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
    }

    // 停止监听
    fun stopListening() {
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
    }

    private fun handleTargetSimCall(context: Context, number: String, state: Int) {
        // 这里实现你的来电处理逻辑,比如拦截、记录等
        Log.d("CallMonitor", "收到指定SIM卡来电:$number")
        // sendToHandlers(context, number, state.toString(), ...)
    }
}

3. 获取目标SIM卡的PhoneAccountId

提前获取设备上所有SIM卡的PhoneAccountHandle信息,找到你需要监听的SIM卡并保存其id:

fun getPhoneAccounts(context: Context): List<PhoneAccount> {
    val telecomManager = context.getSystemService(TelecomManager::class.java)
    return telecomManager.callCapablePhoneAccounts
}

遍历返回的PhoneAccount列表,通过account.label(SIM卡名称)或account.id来识别目标SIM卡,保存对应的id值。

方案优势

  • 准确性高:直接从系统回调获取当前通话的SIM卡信息,无需依赖延迟查询通话记录,避免拿到历史数据的问题。
  • 实时性强:来电状态变化时立即触发回调,响应更及时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:02:37