Jireh程序猿的那些事 Jireh程序猿的那些事

记录分享生活、程序、信息的精彩人生

目录
Android获取双卡手机IMEI等信息
/    

Android获取双卡手机IMEI等信息

上次在写手机数据保存的时候本来想加上去的,但后来觉得太多了。这次就分开来写下双卡手机获取的坑,因为在国外是没有手机双卡双待的功能的,在以前双卡双待还是国内山寨机的必备,现在基本上都比较流行。讲一下原理:双卡手机用我们之前的 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);
        }
    }

}

如果觉得这篇文章不错的话,请我喝一杯 咖啡☕吧
标题:Android获取双卡手机IMEI等信息
作者:Jireh
地址:https://jireh.xyz/articles/2020/03/10/1583805074439.html
本作品由 Jireh 采用 署名 – 非商业性使用 – 禁止演绎 4.0 国际许可协议进行许可,转载请注明出处。