关于android各种双卡手机获取imei,imsi的处理(mtk,展讯,高通等)
目前国内对于双卡智能手机的需求还是很大的,各种复杂的业务会涉及到双卡模块;而android标准的api又不提供对双卡的支持。导致国内双卡模块标准混乱,各个厂商各玩各的。目前我知道的双卡解决方案就有:mtk,展讯,高通,broadcom等。
由于公司业务需要,必须要对双卡手机获取各自的imei,imsi,所以也做了一些研究:
首先是最为应用广泛的mtk平台,国内山寨手机以及一些低端品牌双卡都是做的mtk的双卡解决方案
private static void initMtkDoubleSim() {
try {
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> c = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = c.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
simId_1 = (Integer) fields1.get(null);
Field fields2 = c.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
simId_2 = (Integer) fields2.get(null);
Method m = TelephonyManager.class.getDeclaredMethod(
"getSubscriberIdGemini", int.class);
imsi_1 = (String) m.invoke(tm, simId_1);
imsi_2 = (String) m.invoke(tm, simId_2);
Method m1 = TelephonyManager.class.getDeclaredMethod(
"getDeviceIdGemini", int.class);
imei_1 = (String) m1.invoke(tm, simId_1);
imei_2 = (String) m1.invoke(tm, simId_2);
Method mx = TelephonyManager.class.getDeclaredMethod(
"getPhoneTypeGemini", int.class);
phoneType_1 = (Integer) mx.invoke(tm, simId_1);
phoneType_2 = (Integer) mx.invoke(tm, simId_2);
if (TextUtils.isEmpty(imsi_1) && (!TextUtils.isEmpty(imsi_2))) {
defaultImsi = imsi_2;
}
if (TextUtils.isEmpty(imsi_2) && (!TextUtils.isEmpty(imsi_1))) {
defaultImsi = imsi_1;
}
} catch (Exception e) {
isMtkDoubleSim = false;
return;
}
isMtkDoubleSim = true;
}
可见,在TelephonyManager中提供了**Gemini的方法,可以用反射很方便地获取到相应的信息。
还有
private static void initMtkSecondDoubleSim() {
try {
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> c = Class.forName("com.android.internal.telephony.Phone");
Field fields1 = c.getField("GEMINI_SIM_1");
fields1.setAccessible(true);
simId_1 = (Integer) fields1.get(null);
Field fields2 = c.getField("GEMINI_SIM_2");
fields2.setAccessible(true);
simId_2 = (Integer) fields2.get(null);
Method mx = TelephonyManager.class.getMethod("getDefault",
int.class);
TelephonyManager tm1 = (TelephonyManager) mx.invoke(tm, simId_1);
TelephonyManager tm2 = (TelephonyManager) mx.invoke(tm, simId_2);
imsi_1 = tm1.getSubscriberId();
imsi_2 = tm2.getSubscriberId();
imei_1 = tm1.getDeviceId();
imei_2 = tm2.getDeviceId();
phoneType_1 = tm1.getPhoneType();
phoneType_2 = tm2.getPhoneType();
if (TextUtils.isEmpty(imsi_1) && (!TextUtils.isEmpty(imsi_2))) {
defaultImsi = imsi_2;
}
if (TextUtils.isEmpty(imsi_2) && (!TextUtils.isEmpty(imsi_1))) {
defaultImsi = imsi_1;
}
} catch (Exception e) {
isMtkSecondDoubleSim = false;
return;
}
isMtkSecondDoubleSim = true;
}
看样子有似乎也是属于mtk平台的解决方案,因为都有GEMINI_SIM_1属性,这种双卡方案只在联想278t上发现过;有两个TelephonyManager实例,根据getDefault方法获取
下面是展讯平台的(貌似市面上手机不多啊):
private static void initSpreadDoubleSim() {
try {
Class<?> c = Class
.forName("com.android.internal.telephony.PhoneFactory");
Method m = c.getMethod("getServiceName", String.class, int.class);
spreadTmService = (String) m
.invoke(c, Context.TELEPHONY_SERVICE, 1);
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
imsi_1 = tm.getSubscriberId();
imei_1 = tm.getDeviceId();
phoneType_1 = tm.getPhoneType();
TelephonyManager tm1 = (TelephonyManager) mContext.getSystemService(spreadTmService);
imsi_2 = tm1.getSubscriberId();
imei_2 = tm1.getDeviceId();
phoneType_2 = tm1.getPhoneType();
if (TextUtils.isEmpty(imsi_1) && (!TextUtils.isEmpty(imsi_2))) {
defaultImsi = imsi_2;
}
if (TextUtils.isEmpty(imsi_2) && (!TextUtils.isEmpty(imsi_1))) {
defaultImsi = imsi_1;
}
} catch (Exception e) {
isSpreadDoubleSim = false;
return;
}
isSpreadDoubleSim = true;
}
这个没有展讯sdk的话还是很难找的吧?
下面是高通的:(貌似高通做的不咋的有些接口没有双卡实现啊)
public static void initQualcommDoubleSim() {
try {
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> cx = Class
.forName("android.telephony.MSimTelephonyManager");
Object obj =mContext.getSystemService(
"phone_msim");
simId_1 = 0;
simId_2 = 1;
Method mx = cx.getMethod("getDataState");
// int stateimei_1 = (Integer) mx.invoke(cx.newInstance());
int stateimei_2 = tm.getDataState();
Method mde = cx.getMethod("getDefault");
Method md = cx.getMethod("getDeviceId", int.class);
Method ms = cx.getMethod("getSubscriberId", int.class);
Method mp = cx.getMethod("getPhoneType");
// Object obj = mde.invoke(cx);
imei_1 = (String) md.invoke(obj, simId_1);
imei_2 = (String) md.invoke(obj, simId_2);
imsi_1 = (String) ms.invoke(obj, simId_1);
imsi_2 = (String) ms.invoke(obj, simId_2);
int statephoneType_1 = tm.getDataState();
int statephoneType_2 = (Integer) mx.invoke(obj);
Log.e("tag", statephoneType_1 + "---" + statephoneType_2);
// Class<?> msc = Class.forName("android.telephony.MSimSmsManager");
// for (Method m : msc.getMethods()) {
// if (m.getName().equals("sendTextMessage")) {
// m.getParameterTypes();
// }
// Log.e("tag", m.getName());
// }
} catch (Exception e) {
isQualcommDoubleSim = false;
return;
}
isQualcommDoubleSim = true;
}
getPhoneType&getDataState 方法看了底层发现没有双卡实现,目前也不知道该咋办...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!