Android双卡手机:获取主卡副卡的simid(上)方案实现

本文介绍了在Android双卡手机中获取副卡SubscriberId的挑战和解决方案,涉及高通、华为、三星和联发科等不同芯片厂商的反射方法。文章详细讲解了反射获取过程中的异常处理和注意事项,并指出由于厂商差异,无法保证卡与卡槽的一一对应。下篇将讨论如何实现机型自适配的稳定API。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期公司下发了新任务,需要对Android手机进行双sim卡的管控,而这个功能的关键在于的准确的获取sim卡的SubscriberId值,做过sim卡相关或者电话功能的工程师会很清楚,Android SDK提供了一个方法来获取sim卡的getSubscriberId值。可是这只能获取其中主卡的id值,而副卡根本没有提供API,而且国内的手机大多是双卡手机,所以笔者花了很大功夫调研了大部分市场的畅销Android手机的双卡功能。

整个功能比较繁琐,所以一共分上下两部分讲述。上部讲述市场上主流手机获取副卡Id的方法,以及遇到的困难,注意事项;下部讲述如何整合所有的方案,实现机型自适配,提供一个稳定的API,供其他程序使用。

原生的Android是不支持双卡双待功能的,所以Android sdk没有提供API,直到在Android6.0+上增加了相关的API,但是国内的android嘛,有6.0和没6.0没啥区别,碎片化导致只能利用另外一种方法去获取了—反射。关于反射相关的知识,这里就不进行讲解了,因为获取副卡id会用到大量的反射,不懂的读者可以学习这篇博文[http://www.cnblogs.com/lzq198754/p/5780331.html。]

先说说最困难的地方吧,国内的双卡功能是由厂商联合芯片开发商定做的,所以芯片商不一样,厂商不一样,实现方案也就不一样,所以反射的类和函数名也不一样。总的来说,目前全球有高通(小米),联发科(魅族),麒麟海思(华为),猎户座(三星)四家移动通讯芯片制造商,笔者通过一周的时间,将公司的所有测试机进行了反射获取,终于总结出了如下方案:

  • 高通系:
    代表手机:小米,vivo,oppo
    反射的类:TelephonyManager
    反射方法:getSubscriberId(int id)
    反射方法:getSubscriberId(long id)

    高通系手机获取副卡的API还算规范化,直接在android的原生类中添加了方法,而android6.0+提供的官方双卡API也是这样做的。android提供获取simid原生单卡API为:

TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String id = telephonyManager.getSubscriberId();

所以使用部分厂商直接在TelephonyManager类中重载了该方法, 不过厂商的重载的参数不同,比如笔者在进开发时发现,小米,红米系列使用的重载方法为getSubscriberId(int id),而vivo,oppo,中兴则使用getSubscriberId(long id),反射的代码如下:

public int getSecondImsi(Context context) throws InvocationTargetException,IllegalAccessException, NoSuchMethodException {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        Class<?> telephony
<think>好的,我现在需要回答用户关于SIM中index顺序的编程使用问题。首先,我得理解用户的具体需求。用户提到了“SIM index 顺序 编程 使用”,可能是指如何在编程中操作SIM的索引顺序,比如访问不同的SIM槽或管理多个SIM。 首先,我应该回顾一下SIM的基本结构和管理方式。SIM通常有文件系统,包括MF(文件)、DF(专用文件)和EF(基本文件)。这些文件可能有不同的标识符,比如EF文件通常用2字节的ID标识。不过用户的问题更偏向于索引顺序,这可能涉及到多SIM的管理,比如手机中的槽选择。 接下来,我需要考虑不同平台上的编程方法。例如,在Android系统中,可以使用TelephonyManager来获取SIM的相关信息。可能需要检查是否有API可以访问SIM的索引或槽位。例如,getSimState(int slotIndex)方法中的slotIndex参数可能对应不同的槽。 然后,Java中的示例代码可能涉及获取TelephonyManager实例,并通过getSimOperatorNameForSubscription(int subId)等方法获取不同SIM的信息。需要确认subId和slotIndex之间的关系,以及如何遍历所有激活的SIM。 另外,用户可能需要在应用程序中切换使用不同的SIM进行拨号或发送短信。这需要检查权限,如READ_PHONE_STATE,并处理多SIM的API调用。例如,使用Intent附加extra来指定使用的SIM。 还需要考虑不同Android版本的差异,因为某些API可能在较新或较旧的版本中可用。例如,多SIM支持在Android 5.1(API 22)及更高版本中更为完善。 此外,SIM的索引顺序可能因设备制造商而异,有些设备可能将slot 0作为,slot 1作为,但需要提醒用户注意设备差异和兼容性问题。 最后,总结关键点,包括文件结构、Android API的使用、代码示例、权限和注意事项。同时,生成相关问题,帮助用户深入理解多SIM编程的各个方面。</think>### SIM索引顺序编程解析 #### 1. SIM文件结构索引 SIM采用树形文件系统管理数据,索引顺序通过文件标识符(FID)实现: - 文件(MF)固定为$3F00$ - 专用文件(DF)如$7F10$(电信目录) - 基本文件(EF)如$6F3A$(短信存储) 编程访问示例(APDU命令): ```java // 选择文件 String selectMF = "00A40004023F00"; // 读取EF_ICCID文件 String readICCID = "00B000000A"; ``` #### 2. Android槽索引 Android系统通过TelephonyManager管理多SIM: ```java TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); int slotCount = tm.getPhoneCount(); // 获取槽数量 // 获取指定槽信息 if (slotCount > 1) { SubscriptionManager subMgr = getSystemService(SubscriptionManager.class); List<SubscriptionInfo> subInfoList = subMgr.getActiveSubscriptionInfoList(); for (SubscriptionInfo subInfo : subInfoList) { int slotIndex = subInfo.getSimSlotIndex(); // 0或1 String iccid = subInfo.getIccId(); } } ``` #### 3. 拨号实现 指定SIM拨号需要添加额外参数: ```java Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:10086")); // 添加槽索引参数 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { intent.putExtra("android.telecom.extra.PHONE_ACCOUNT_HANDLE", TelecomManager.from(context).getCallCapablePhoneAccounts().get(slotIndex)); } startActivity(intent); ``` #### 4. 关键注意事项 1. 权限声明: ```xml <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.CALL_PHONE"/> ``` 2. 兼容性处理: ```java if (SubscriptionManager.from(context).getActiveSubscriptionInfoCount() > 1) { // 设备处理逻辑 } else { // 单设备备用方案 } ``` 3. 索引映射验证: 不同设备可能采用不同映射策略(如物理槽与逻辑索引的对应关系),建议通过`SubscriptionInfo.getSimSlotIndex()`动态获取[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值