上次在写手机数据保存的时候本来想加上去的,但后来觉得太多了。这次就分开来写下双卡手机获取的坑,因为在国外是没有手机双卡双待的功能的,在以前双卡双待还是国内山寨机的必备,现在基本上都比较流行。讲一下原理:双卡手机用我们之前的 TelephonyManager 是获取不到的,必须使用的反射的方法来实现,通过手机上卡槽的编号,来获取相对应卡槽编号的 sim 卡信息。
好了接下来直接上代码,
public String getImsi0 (Context context) { String imsi = ""; try { TelephonyManager tm = (TelephonyManager) context. getSystemService(Context.TELEPHONY_SERVICE); //普通方法获取 //imsi = tm.getSubscriberId(); /*if (imsi==null || "".equals(imsi)) imsi = tm.getSimOperator();*/ Class<?>[] resources = new Class<?>[] {int.class}; Integer resourcesId = new Integer(0);//这里是卡槽的编号 if (imsi==null || "".equals(imsi)) { try { //反射展讯 Method addMethod = tm.getClass().getDeclaredMethod("getSubscriberIdGemini", resources); addMethod.setAccessible(true); imsi = (String) addMethod.invoke(tm, resourcesId); } catch (Exception e) { imsi = null; } } if (imsi==null || "".equals(imsi)) { try { //反射mtk Class<?> c = Class .forName("com.android.internal.telephony.PhoneFactory"); Method m = c.getMethod("getServiceName", String.class, int.class); String spreadTmService = (String) m.invoke(c, Context.TELEPHONY_SERVICE, resourcesId); TelephonyManager tm1 = (TelephonyManager) context.getSystemService(spreadTmService); imsi = tm1.getSubscriberId(); } catch (Exception e) { imsi = null; } } if (imsi==null || "".equals(imsi)) { try { //反射高通 这个没测过 Method addMethod2 = tm.getClass().getDeclaredMethod("getSubscriberId", resources); addMethod2.setAccessible(true); imsi = (String) addMethod2.invoke(tm, resourcesId); } catch (Exception e) { imsi = null; } } if (imsi==null || "".equals(imsi)) { imsi = "000000"; } return imsi; } catch (Exception e) { return "000000"; } }
用时候直接这样就好了,需要引用 context
private Context cxt; public YouClass(Context context){ cxt=context; }
imei1=getImsi1(cxt));
代码的流程就是检测手机的的芯片,在用反射机制根据卡槽编号 resourcesId 查询 sim 卡信息
Method addMethod2 = tm.getClass().getDeclaredMethod("getSubscriberId", resources);
讲一下我在研究的时候碰到的一些问题,之前在查找一些资料的时候,他们的检测卡槽,只检测 0,1 卡槽,但是后来我在测试的时候,只获取到一个卡槽 1 的信息,另外一个就是没有,后来我就多检测卡槽 2,就获取到了,可能是因为这个编号从 1 开始吧,到时候大家可以多测试下一个卡槽哈。
其他的卡槽的代码复制了,改下 Integer resourcesId = new Integer(0); 这里的 0,这个 0 就是编号,如果大家有机会可以多测试几个 1、2、3 都可以试下是什么效果。
然后根据这个原理,弄了一个 Uitl 类,方便调用。
package com.yyxt.jireh.gpst2.Util; /** * 2017年8月25日 10:10:58 * Jireh * www.lyile.cn * admin@lyile.cn * 通过反射机制 * 获取相对应卡槽sim卡相关信息Uitl */ import android.content.Context; import android.telephony.TelephonyManager; import android.text.TextUtils; import java.lang.reflect.Method; public class CTelephoneInfo { private static final String TAG = CTelephoneInfo.class.getSimpleName(); private String imeiSIM1;// IMEI private String imeiSIM2;//IMEI private String iNumeric1;//sim1 code number private boolean isSIM1Ready;//sim1 private String iNumeric2;//sim2 code number private String iSimSerialNumber1; private String iSimSerialNumber2; private boolean isSIM2Ready;//sim2 private String iPhoneNumber1;// private String iPhoneNumber2;// private String iDataConnected1 = "0";//sim1 0 no, 1 connecting, 2 connected, 3 suspended. private String iDataConnected2 = "0";//sim2 private static CTelephoneInfo CTelephoneInfo; private static Context mContext; private String PhoneId; private CTelephoneInfo() { } public synchronized static CTelephoneInfo getInstance(Context context){ if(CTelephoneInfo == null) { CTelephoneInfo = new CTelephoneInfo(); } mContext = context; return CTelephoneInfo; } public static CTelephoneInfo setPhoneId(String phid){ CTelephoneInfo.PhoneId=phid; return CTelephoneInfo; } public String getPhoneId(){ return PhoneId; } public String getImeiSIM1() { return imeiSIM1; } public String getImeiSIM2() { return imeiSIM2; } public String getiPhoneNumber1() { return iPhoneNumber1; } public String getiPhoneNumber2() { return iPhoneNumber2; } public String getiSimSerialNumber2() { return iSimSerialNumber2; } public boolean isSIM1Ready() { return isSIM1Ready; } public boolean isSIM2Ready() { return isSIM2Ready; } public boolean isDualSim(){ return imeiSIM2 != null; } public boolean isDataConnected1(){ if(TextUtils.equals(iDataConnected1, "2")||TextUtils.equals(iDataConnected1, "1")) return true; else return false; } public boolean isDataConnected2(){ if(TextUtils.equals(iDataConnected2, "2")||TextUtils.equals(iDataConnected2, "1")) return true; else return false; } public String getINumeric1(){ return iNumeric1; } public String getINumeric2(){ return iNumeric2; } public String getISimSerialNumber1() { return iSimSerialNumber1; } public String getISimSerialNumber2() { return iSimSerialNumber2; } public String getINumeric(){ if(imeiSIM2 != null){ if(iNumeric1 != null && iNumeric1.length() > 1) return iNumeric1; if(iNumeric2 != null && iNumeric2.length() > 1) return iNumeric2; } return iNumeric1; } public void setCTelephoneInfo(){ TelephonyManager telephonyManager = ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)); CTelephoneInfo.imeiSIM1 = null; CTelephoneInfo.imeiSIM2 = null; try { CTelephoneInfo.imeiSIM1 = getOperatorBySlot(mContext, "getDeviceIdGemini", 1); CTelephoneInfo.imeiSIM2 = getOperatorBySlot(mContext, "getDeviceIdGemini", 2); CTelephoneInfo.iSimSerialNumber1 = getOperatorBySlot(mContext, "getSimSerialNumberGemini", 1); CTelephoneInfo.iSimSerialNumber2 = getOperatorBySlot(mContext, "getSimSerialNumberGemini", 2); /*CTelephoneInfo.iPhoneNumber1=getOperatorBySlot(mContext,"getLine1NumberGemini",1); CTelephoneInfo.iPhoneNumber2=getOperatorBySlot(mContext,"getLine1NumberGemini",2);*/ CTelephoneInfo.iNumeric1 = getOperatorBySlot(mContext, "getSubscriberIdGemini", 1); CTelephoneInfo.iNumeric2 = getOperatorBySlot(mContext, "getSubscriberIdGemini", 2); CTelephoneInfo.iDataConnected1 = getOperatorBySlot(mContext, "getDataStateGemini", 1); CTelephoneInfo.iDataConnected2 = getOperatorBySlot(mContext, "getDataStateGemini", 2); } catch (GeminiMethodNotFoundException e) { e.printStackTrace(); try { CTelephoneInfo.imeiSIM1 = getOperatorBySlot(mContext, "getDeviceId", 1); CTelephoneInfo.imeiSIM2 = getOperatorBySlot(mContext, "getDeviceId", 2); CTelephoneInfo.iSimSerialNumber1 = getOperatorBySlot(mContext, "getSimSerialNumber", 1); CTelephoneInfo.iSimSerialNumber2 = getOperatorBySlot(mContext, "getSimSerialNumber", 2); /*CTelephoneInfo.iPhoneNumber1=getOperatorBySlot(mContext,"getLine1Number",1); CTelephoneInfo.iPhoneNumber2=getOperatorBySlot(mContext,"getLine1Number",2);*/ CTelephoneInfo.iNumeric1 = getOperatorBySlot(mContext, "getSubscriberId", 1); CTelephoneInfo.iNumeric2 = getOperatorBySlot(mContext, "getSubscriberId", 2); CTelephoneInfo.iDataConnected1 = getOperatorBySlot(mContext, "getDataState", 1); CTelephoneInfo.iDataConnected2 = getOperatorBySlot(mContext, "getDataState", 2); } catch (GeminiMethodNotFoundException e1) { //Call here for next manufacturer's predicted method name if you wish e1.printStackTrace(); } } CTelephoneInfo.isSIM1Ready = telephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY; CTelephoneInfo.isSIM2Ready = false; try { CTelephoneInfo.isSIM1Ready = getSIMStateBySlot(mContext, "getSimStateGemini", 0); CTelephoneInfo.isSIM2Ready = getSIMStateBySlot(mContext, "getSimStateGemini", 1); } catch (GeminiMethodNotFoundException e) { e.printStackTrace(); try { CTelephoneInfo.isSIM1Ready = getSIMStateBySlot(mContext, "getSimState", 0); CTelephoneInfo.isSIM2Ready = getSIMStateBySlot(mContext, "getSimState", 1); } catch (GeminiMethodNotFoundException e1) { //Call here for next manufacturer's predicted method name if you wish e1.printStackTrace(); } } } private static String getOperatorBySlot(Context context, String predictedMethodName, int slotID) throws GeminiMethodNotFoundException { String inumeric = null; TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); try{ Class<?> telephonyClass = Class.forName(telephony.getClass().getName()); Class<?>[] parameter = new Class[1]; parameter[0] = int.class; Method getSimID = telephonyClass.getMethod(predictedMethodName, parameter); Object[] obParameter = new Object[1]; obParameter[0] = slotID; Object ob_phone = getSimID.invoke(telephony, obParameter); if(ob_phone != null){ inumeric = ob_phone.toString(); } } catch (Exception e) { e.printStackTrace(); throw new GeminiMethodNotFoundException(predictedMethodName); } return inumeric; } private static boolean getSIMStateBySlot(Context context, String predictedMethodName, int slotID) throws GeminiMethodNotFoundException { boolean isReady = false; TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); try{ Class<?> telephonyClass = Class.forName(telephony.getClass().getName()); Class<?>[] parameter = new Class[1]; parameter[0] = int.class; Method getSimStateGemini = telephonyClass.getMethod(predictedMethodName, parameter); Object[] obParameter = new Object[1]; obParameter[0] = slotID; Object ob_phone = getSimStateGemini.invoke(telephony, obParameter); if(ob_phone != null){ int simState = Integer.parseInt(ob_phone.toString()); if(simState == TelephonyManager.SIM_STATE_READY){ isReady = true; } } } catch (Exception e) { e.printStackTrace(); throw new GeminiMethodNotFoundException(predictedMethodName); } return isReady; } private static class GeminiMethodNotFoundException extends Exception { /** * */ private static final long serialVersionUID = -3241033488141442594L; public GeminiMethodNotFoundException(String info) { super(info); } } }