Android双卡设备中如何识别来电对应的SIM卡?
双卡设备中通过Broadcast Receiver识别来电SIM卡的方法
原生系统通过TelephonyManager发送的来电广播默认不会直接携带SIM卡槽信息,可通过以下几种方式实现识别:
1. 读取系统隐藏Extra字段
部分Android版本或厂商会在广播Intent中添加隐藏的卡槽相关字段,你可以尝试读取:
TelephonyManager.EXTRA_SLOT_INDEX:对应卡槽索引(通常为0或1,部分设备从1开始计数)subscription:对应SIM卡的订阅ID
修改你的onReceive方法,添加读取逻辑:
public void onReceive(Context context, Intent intent) { String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER); // 尝试读取卡槽索引 int slotIndex = intent.getExtras().getInt(TelephonyManager.EXTRA_SLOT_INDEX, -1); // 尝试读取订阅ID int subscriptionId = intent.getExtras().getInt("subscription", -1); if (slotIndex != -1) { Log.d("IncomingCall", "来电来自卡槽:" + (slotIndex + 1)); } else if (subscriptionId != -1) { SubscriptionManager subscriptionManager = SubscriptionManager.from(context); SubscriptionInfo info = subscriptionManager.getActiveSubscriptionInfo(subscriptionId); if (info != null) { Log.d("IncomingCall", "来电来自卡槽:" + (info.getSimSlotIndex() + 1)); } } }
注意:这些属于非公开API,不同厂商、版本的兼容性无法保证。
2. 通过SubscriptionManager关联来电号码与SIM卡
若无法读取隐藏字段,可通过SubscriptionManager获取所有活跃SIM卡的号码信息,再与来电号码匹配:
步骤说明:
- 权限申请:在
AndroidManifest.xml中添加READ_PHONE_STATE(Android 9及以下)或READ_PHONE_NUMBERS(Android 10及以上)权限,并在运行时动态申请。 - 获取所有活跃SIM卡的订阅信息,建立号码与卡槽的对应关系。
- 来电时格式化号码并匹配,找到对应SIM卡槽。
示例代码:
public void onReceive(Context context, Intent intent) { String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); String incomingNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER); if (TextUtils.isEmpty(incomingNumber)) { return; } // 格式化号码,去除空格、区号等干扰项 String formattedIncoming = PhoneNumberUtils.formatNumber(incomingNumber); SubscriptionManager subscriptionManager = SubscriptionManager.from(context); List<SubscriptionInfo> activeSubscriptions = subscriptionManager.getActiveSubscriptionInfoList(); for (SubscriptionInfo info : activeSubscriptions) { String simNumber = info.getNumber(); if (!TextUtils.isEmpty(simNumber)) { String formattedSimNumber = PhoneNumberUtils.formatNumber(simNumber); if (formattedIncoming.equals(formattedSimNumber)) { int slotIndex = info.getSimSlotIndex(); Log.d("IncomingCall", "来电来自卡槽:" + (slotIndex + 1)); break; } } } }
注意:若用户隐藏了SIM号码,该方法会失效;需处理不同地区的号码格式化逻辑,确保匹配准确。
3. 适配厂商自定义字段
部分厂商(如小米、华为)会在来电广播中添加自定义Extra字段,例如:
- 小米:
com.android.phone.extra.slot - 华为:
slot_id
可针对特定厂商尝试读取这些字段,但仅适用于特定场景,兼容性较差。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

