双卡手机如何获取指定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
相关产品推荐
相关产品推荐

