当前位置: 首页 > 知识库问答 >
问题:

Android:检查手机是否为双SIM卡

段干恺
2023-03-14

经过论坛上的大量研究,现在我知道没有办法找到双SIM卡手机中两个SIM卡的IMSI或SIM序列号(除了联系制造商)。现在我改变的问题是,我们能检测到手机有两个模拟人生吗?我相信只要有一些情报就可以检测到。我能想到的几个方法是:

>

  • 拨打USSD代码并跟踪IMEI号码的日志(我在印度尝试了*139#。它起作用了。)这将给我IMEI号码的SIM卡,我从其中拨打USSD代码。(据推测,这款手机遵循Android指南,有两个IMEI号码。)

    存储SIM卡序列号和/或SIM卡的IMSI。通过跟踪一些日志或通过一些广播事件处理,检测到任何其他IMSI/序列号后,即使手机未重新启动(即SIM卡已切换)。

    通过拨打*06#,您将看到两个IMEI号码。通过某种方式,得到这两个数字。(类似于屏幕捕获和文本图像解析。)

    如果有人能想出其他的办法,他们是最受欢迎的。我真的非常感谢任何关于这方面的帮助。此外,如果任何人有任何关于制造商API的信息或联系他们的链接,请与社区人员共享。

  • 共有3个答案

    宰坚
    2023-03-14

    在搜索检查网络运营商的方法时,我发现了几个本地解决方案。

    用于API

    TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    
    // Get information about all radio modules on device board
    // and check what you need by calling #getCellIdentity.
    
    final List<CellInfo> allCellInfo = manager.getAllCellInfo();
    for (CellInfo cellInfo : allCellInfo) {
        if (cellInfo instanceof CellInfoGsm) {
            CellIdentityGsm cellIdentity = ((CellInfoGsm) cellInfo).getCellIdentity();
            //TODO Use cellIdentity to check MCC/MNC code, for instance.
        } else if (cellInfo instanceof CellInfoWcdma) {
            CellIdentityWcdma cellIdentity = ((CellInfoWcdma) cellInfo).getCellIdentity();
        } else if (cellInfo instanceof CellInfoLte) {
            CellIdentityLte cellIdentity = ((CellInfoLte) cellInfo).getCellIdentity();
        } else if (cellInfo instanceof CellInfoCdma) {
            CellIdentityCdma cellIdentity = ((CellInfoCdma) cellInfo).getCellIdentity();
        } 
    }
    

    在Android清单中添加权限:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    </manifest>
    

    要获得网络运营商,您可以检查mcc和mnc代码:

    • https://en.wikipedia.org/wiki/Mobile_country_code(一般资料)
    • https://clients.txtnation.com/hc/en-us/articles/218719768-MCCMNC-mobile-country-code-and-mobile-network-code-list-(运营商名单非常完整,也是最新的)

    用于API

    final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
    final List<SubscriptionInfo> activeSubscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
    for (SubscriptionInfo subscriptionInfo : activeSubscriptionInfoList) {
        final CharSequence carrierName = subscriptionInfo.getCarrierName();
        final CharSequence displayName = subscriptionInfo.getDisplayName();
        final int mcc = subscriptionInfo.getMcc();
        final int mnc = subscriptionInfo.getMnc();
        final String subscriptionInfoNumber = subscriptionInfo.getNumber();
    }
    

    用于API

    TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    if (manager.getPhoneCount() == 2) {
        // Dual sim
    }
    
    程磊
    2023-03-14

    我有一个三星Duos设备与Android 4.4.4和Seetha在接受的答案中建议的方法(即调用getDeviceIdDs)不适合我,因为该方法不存在。我能够通过调用方法getDefault(int slotID)恢复我需要的所有信息,如下所示:

    public static void samsungTwoSims(Context context) {
        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 getFirstMethod = telephonyClass.getMethod("getDefault", parameter);
    
            Log.d(TAG, getFirstMethod.toString());
    
            Object[] obParameter = new Object[1];
            obParameter[0] = 0;
            TelephonyManager first = (TelephonyManager) getFirstMethod.invoke(null, obParameter);
    
            Log.d(TAG, "Device Id: " + first.getDeviceId() + ", device status: " + first.getSimState() + ", operator: " + first.getNetworkOperator() + "/" + first.getNetworkOperatorName());
    
            obParameter[0] = 1;
            TelephonyManager second = (TelephonyManager) getFirstMethod.invoke(null, obParameter);
    
            Log.d(TAG, "Device Id: " + second.getDeviceId() + ", device status: " + second.getSimState()+ ", operator: " + second.getNetworkOperator() + "/" + second.getNetworkOperatorName());
        } catch (Exception e) {
            e.printStackTrace();
        }   
    }
    

    此外,我重写了迭代测试方法以恢复此信息的代码,以便它使用方法名称数组而不是try/catch序列。例如,要确定是否有两个活动SIM,我们可以执行以下操作:

    private static String[] simStatusMethodNames = {"getSimStateGemini", "getSimState"};
    
    
    public static boolean hasTwoActiveSims(Context context) {
        boolean first = false, second = false;
    
        for (String methodName: simStatusMethodNames) {
            // try with sim 0 first
            try {
                first = getSIMStateBySlot(context, methodName, 0);
                // no exception thrown, means method exists
                second = getSIMStateBySlot(context, methodName, 1);
               return first && second;
            } catch (GeminiMethodNotFoundException e) {
                // method does not exist, nothing to do but test the next
            }
        }
        return false;
    }
    

    这样,如果为某些设备建议了一个新方法名称,您可以简单地将其添加到数组中,它应该可以工作。

    太叔小云
    2023-03-14

    2015年3月23日更新:

    官方多SIM卡API现在可从Android 5.1起

    其他可能的选择:

    您可以使用Java反射来获取两个IMEI编号。

    使用这些IMEI号码,您可以检查手机是否为双SIM卡。

    尝试以下活动:

    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TelephonyInfo telephonyInfo = TelephonyInfo.getInstance(this);
    
            String imeiSIM1 = telephonyInfo.getImsiSIM1();
            String imeiSIM2 = telephonyInfo.getImsiSIM2();
    
            boolean isSIM1Ready = telephonyInfo.isSIM1Ready();
            boolean isSIM2Ready = telephonyInfo.isSIM2Ready();
    
            boolean isDualSIM = telephonyInfo.isDualSIM();
    
            TextView tv = (TextView) findViewById(R.id.tv);
            tv.setText(" IME1 : " + imeiSIM1 + "\n" +
                    " IME2 : " + imeiSIM2 + "\n" +
                    " IS DUAL SIM : " + isDualSIM + "\n" +
                    " IS SIM1 READY : " + isSIM1Ready + "\n" +
                    " IS SIM2 READY : " + isSIM2Ready + "\n");
        }
    }
    

    这里是TelephonyInfo。java

    import java.lang.reflect.Method;
    
    import android.content.Context;
    import android.telephony.TelephonyManager;
    
    public final class TelephonyInfo {
    
        private static TelephonyInfo telephonyInfo;
        private String imeiSIM1;
        private String imeiSIM2;
        private boolean isSIM1Ready;
        private boolean isSIM2Ready;
    
        public String getImsiSIM1() {
            return imeiSIM1;
        }
    
        /*public static void setImsiSIM1(String imeiSIM1) {
            TelephonyInfo.imeiSIM1 = imeiSIM1;
        }*/
    
        public String getImsiSIM2() {
            return imeiSIM2;
        }
    
        /*public static void setImsiSIM2(String imeiSIM2) {
            TelephonyInfo.imeiSIM2 = imeiSIM2;
        }*/
    
        public boolean isSIM1Ready() {
            return isSIM1Ready;
        }
    
        /*public static void setSIM1Ready(boolean isSIM1Ready) {
            TelephonyInfo.isSIM1Ready = isSIM1Ready;
        }*/
    
        public boolean isSIM2Ready() {
            return isSIM2Ready;
        }
    
        /*public static void setSIM2Ready(boolean isSIM2Ready) {
            TelephonyInfo.isSIM2Ready = isSIM2Ready;
        }*/
    
        public boolean isDualSIM() {
            return imeiSIM2 != null;
        }
    
        private TelephonyInfo() {
        }
    
        public static TelephonyInfo getInstance(Context context){
    
            if(telephonyInfo == null) {
    
                telephonyInfo = new TelephonyInfo();
    
                TelephonyManager telephonyManager = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE));
    
                telephonyInfo.imeiSIM1 = telephonyManager.getDeviceId();;
                telephonyInfo.imeiSIM2 = null;
    
                try {
                    telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceIdGemini", 0);
                    telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceIdGemini", 1);
                } catch (GeminiMethodNotFoundException e) {
                    e.printStackTrace();
    
                    try {
                        telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceId", 0);
                        telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceId", 1);
                    } catch (GeminiMethodNotFoundException e1) {
                        //Call here for next manufacturer's predicted method name if you wish
                        e1.printStackTrace();
                    }
                }
    
                telephonyInfo.isSIM1Ready = telephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY;
                telephonyInfo.isSIM2Ready = false;
    
                try {
                    telephonyInfo.isSIM1Ready = getSIMStateBySlot(context, "getSimStateGemini", 0);
                    telephonyInfo.isSIM2Ready = getSIMStateBySlot(context, "getSimStateGemini", 1);
                } catch (GeminiMethodNotFoundException e) {
    
                    e.printStackTrace();
    
                    try {
                        telephonyInfo.isSIM1Ready = getSIMStateBySlot(context, "getSimState", 0);
                        telephonyInfo.isSIM2Ready = getSIMStateBySlot(context, "getSimState", 1);
                    } catch (GeminiMethodNotFoundException e1) {
                        //Call here for next manufacturer's predicted method name if you wish
                        e1.printStackTrace();
                    }
                }
            }
    
            return telephonyInfo;
        }
    
        private static String getDeviceIdBySlot(Context context, String predictedMethodName, int slotID) throws GeminiMethodNotFoundException {
    
            String imei = 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){
                    imei = ob_phone.toString();
    
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new GeminiMethodNotFoundException(predictedMethodName);
            }
    
            return imei;
        }
    
        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 = -996812356902545308L;
    
            public GeminiMethodNotFoundException(String info) {
                super(info);
            }
        }
    }
    

    编辑:

    获取其他SIM卡插槽详细信息的方法,如“getDeviceId251”,预测该方法存在。

    如果该方法的名称与设备制造商给出的名称不匹配,那么它将无法工作。您必须为这些设备找到相应的方法名称。

    可以使用Java反射查找其他制造商的方法名称,如下所示:

    public static void printTelephonyManagerMethodNamesForThisDevice(Context context) {
    
        TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        Class<?> telephonyClass;
        try {
            telephonyClass = Class.forName(telephony.getClass().getName());
            Method[] methods = telephonyClass.getMethods();
            for (int idx = 0; idx < methods.length; idx++) {
    
                System.out.println("\n" + methods[idx] + " declared by " + methods[idx].getDeclaringClass());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    } 
    

    编辑:

    正如Seetha在评论中指出的:

    telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getDeviceIdDs", 0);
    telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getDeviceIdDs", 1); 
    

    它为她工作。她成功地为三星双人手机的两个SIM卡获得了两个IMEI号码。

    添加

    编辑2:

    用于检索数据的方法适用于联想A319和该制造商生产的其他手机(Credit Maher Abuthraa):

    telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 0); 
    telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 1); 
    

     类似资料:
    • 我有一个android应用程序可以检测来电,我需要改进这个应用程序,使其能够在duos移动设备上工作。因此,我创建了一个在清单中注册的广播接收器,用于操作:电话状态已更改,在onReceive方法中,我需要检查哪个sim卡接收呼叫。这是我的密码 我运行这个应用程序上的设备4.2 2和其正常工作,但当我运行它上的设备4 4.4所以这个方法不工作,我的意思是,其中sim返回-1在所有情况下。有人能帮帮

    • 本文向大家介绍android检查手机和无线是否连接的方法,包括了android检查手机和无线是否连接的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了android检查手机和无线是否连接的实现代码,分享给大家供大家参考。具体方法如下: 方法一: 主要功能代码如下: 方法二: 主要功能代码如下: 其中方法一既可以检查手机连接也可以检查手机无线连接状态 方法二只能检查手机连接状态,不能检查

    • 嗨,伙计们,我正在为我的覆盆子Pi家庭服务器写一个智能家庭扩展。为此,我想通过检查智能手机是否连接到本地网络来了解何时有人在家。 不幸的是,到目前为止,ping Android设备在最好的情况下是不可靠的。这取决于睡眠状态,Nexus5x根本不响应ping。我也不去摆弄睡眠设置,因为那会减少电池寿命。 我的路由器说设备已经连接,但我不知道如何中继这个信息。我有什么办法可以确定任何智能手机都是用Py

    • cmf_is_mobile() 功能 判断是否为手机访问 参数 无 返回 boolean

    • 问题内容: 如何检查Android手机是横向还是纵向? 问题答案: 用于确定要检索哪些资源的当前配置可从资源的对象中获得: 你可以通过查看方向值来检查方向:

    • 本文向大家介绍Android手机卫士之绑定sim卡序列号,包括了Android手机卫士之绑定sim卡序列号的使用技巧和注意事项,需要的朋友参考一下 现在开始具体 处理每一个导航页面的逻辑,首先看第二个导航页 这里需要实现绑定sim卡序列号的功能,注意添加相应的权限:uses-permission android:name="android.permission.READ_PHONE_STATE"