You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

开发多SIM卡网络信息App:Registered CellInfo列表是否与反转后的SubscriptionInfo列表关联?

解决SIM卡SubscriptionManager与TelephonyManager数据匹配问题

嘿,我之前在开发双卡相关的Android应用时也踩过类似的坑,完全懂你靠MNC匹配失败、列表顺序反转的崩溃感!给你几个实用的解决方向:

最可靠的方案:用卡槽ID(slotId)关联数据

不要依赖两个管理器返回列表的顺序来匹配,这本来就不稳定——不同Android版本、不同厂商对列表排序的逻辑可能不一样,甚至插拔SIM卡后顺序会乱。卡槽ID才是唯一能准确关联两者数据的标识

具体步骤:

  1. SubscriptionManager获取所有活跃的SIM卡订阅信息,每个SubscriptionInfo都能通过getSlotId()拿到对应的卡槽ID;
  2. 用这个卡槽ID,通过TelephonyManager.createForSlotId(int slotId)创建对应卡槽的TelephonyManager实例,直接获取该卡槽的网络信息。

代码示例:

// 获取SubscriptionManager实例
SubscriptionManager subscriptionManager = 
    (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> activeSubs = subscriptionManager.getActiveSubscriptionInfoList();

if (activeSubs != null) {
    for (SubscriptionInfo subInfo : activeSubs) {
        int slotId = subInfo.getSlotId();
        // 创建对应卡槽的TelephonyManager
        TelephonyManager slotTelephonyManager = 
            TelephonyManager.from(this).createForSlotId(slotId);
        
        // 获取你需要的网络信息
        String networkName = slotTelephonyManager.getNetworkOperatorName();
        String networkType = slotTelephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE 
            ? "LTE" : "其他网络";
        
        // 获取运营商名称(其实SubscriptionInfo本身也能拿到:subInfo.getCarrierName())
        String carrierName = subInfo.getCarrierName().toString();
        
        // 这里处理你的展示逻辑
    }
}

备用方案:统一MCC/MNC格式再匹配

如果你一定要用MCC/MNC做匹配,要注意两者返回的格式可能不一致:

  • SubscriptionInfogetMcc()getMnc()是整数,比如MNC为1时,返回的是1
  • TelephonyManager.getNetworkOperator()返回的是字符串格式的MCC+MNC,比如MNC为1时会补零成01(完整字符串如46001)。

所以需要把两者转换成统一格式再比较:

// 从SubscriptionInfo提取统一格式的MCC+MNC
String subMccMnc = subInfo.getMcc() + String.format("%02d", subInfo.getMnc());
// 从TelephonyManager获取MCC+MNC
String teleMccMnc = slotTelephonyManager.getNetworkOperator();

if (subMccMnc.equals(teleMccMnc)) {
    // 匹配成功
}

⚠️ 注意:这个方法有局限性,如果双卡用的是同一家运营商(MCC/MNC相同),就无法区分卡槽了,所以还是优先用slotId方案。

额外注意事项

  • 权限适配:Android 6.0+需要动态申请READ_PHONE_STATE权限,Android 10+如果需要获取更详细的SIM信息,可能需要READ_PHONE_NUMBERS权限;
  • 空值判断:getActiveSubscriptionInfoList()可能返回null,要先做非空检查再遍历。

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

火山引擎 最新活动