Android: vérifier si le téléphone est double SIM

après beaucoup de recherches sur les forums, maintenant je sais qu'il n'y a aucun moyen de trouver le numéro de série IMSI ou SIM pour les deux cartes SIM dans un téléphone SIM double (sauf pour contacter le fabricant). Maintenant, ma nouvelle question Est, pouvons-nous détecter que le téléphone a deux SIMs? Je crois qu'il peut être détecté avec un peu d'intelligence. Il y a quelques façons auxquelles je peux penser:

  1. composer un code USSD et tracer les logs pour le numéro IMEI (j'ai essayé avec *139# dans l'Inde. Il a travaillé.) Ceci me donnera le numéro IMEI pour la SIM à partir de laquelle j'ai composé le code USSD. (Il est présumé que le téléphone suit les directives android et a deux numéros IMEI.)

  2. enregistrant le numéro de série SIM et/ou IMSI pour le SIM. Et après détection de tout autre numéro IMSI/numéro de série, même si le téléphone n'a pas été redémarré (c.-à-d. que le SIM a été commuté) en traçant certains journaux ou en manipulant un événement de diffusion.

  3. en composant *06# vous pourrez voir les deux numéros IMEI. En quelque sorte, obtenir ces deux nombres. (Quelque chose comme la capture d'écran et l'analyse d'image pour le texte.)

si quelqu'un peut penser à d'autres moyens, ils sont les bienvenus. J'apprécierais vraiment de l'aide à ce sujet. En outre, si quelqu'un a des informations sur les API des fabricants ou des liens pour les contacter, s'il vous plaît partager avec les gens de la communauté.

104
demandé sur xDragonZ 2013-01-25 11:31:06

8 réponses

Mise À Jour 23 Mars'15 :

L'API SIM officielle est disponible à partir de Maintenant à partir D'Android 5.1

autre option possible:

vous pouvez utiliser Java reflection pour obtenir les deux numéros IMEI.

en utilisant ces numéros IMEI vous pouvez vérifier si le téléphone est un Double SIM ou pas.

essayez l'activité suivante:

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");
    }
}

Et voici 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);
        }
    }
}

Edit :

obtenir l'accès de méthodes comme "getDeviceIdGemini" pour le détail D'autres slot SIM a prédiction que la méthode existe.

si le nom de la méthode ne correspond pas à un nom donné par le fabricant de l'appareil ne fonctionnera pas. Vous devez trouver le nom de méthode correspondant pour ces périphériques.

les noms de méthode de recherche pour d'autres fabricants peuvent être faits en utilisant Java reflection comme suit:

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();
    }
} 

EDIT:

comme Seetha a souligné dans son commentaire:

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

ça marche pour elle. Elle a réussi à obtenir deux numéros IMEI pour le SIM dans le Duos Samsung.

ajouter <uses-permission android:name="android.permission.READ_PHONE_STATE" />

EDIT 2 :

la méthode utilisée pour extraire des données est pour Lenovo A319 et d'autres téléphones par cette manufacture (crédit Maher Abuthraa ):

telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 0); 
telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 1); 
170
répondu Vaibhav Jani 2017-07-06 02:07:39

j'ai un appareil Samsung Duos avec Android 4.4.4 et la méthode suggérée par Seetha dans la réponse acceptée (i.e. call getDeviceIdDs) ne fonctionne pas pour moi, que la méthode n'existe pas. J'ai pu récupérer toutes les informations dont j'avais besoin en appelant la méthode "getDefault(int slotID)", comme suit:

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();
    }   
}

aussi, j'ai réécrit le code qui teste itérativement des méthodes pour récupérer cette information de sorte qu'il utilise un tableau de noms de méthode au lieu d'un séquence d'essai / capture. Par exemple, pour déterminer si nous avons deux SIM actifs, nous pourrions faire:

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;
}

de cette façon, si un nouveau nom de méthode est suggéré pour un périphérique, vous pouvez simplement l'ajouter au tableau et cela devrait fonctionner.

5
répondu Eduardo Javier Huerta Yero 2015-09-16 18:41:40

il y a plusieurs solutions natives que j'ai trouvées en cherchant la façon de vérifier l'opérateur réseau.

pour API > = 17:

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();
    } 
}

dans AndroidManifest ajouter autorisation:

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

pour obtenir opérateur de réseau, vous pouvez vérifier les codes mcc et mnc:

pour API > = 22:

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();
}

pour API >=23. Pour vérifier si le téléphone est double / triple / beaucoup sim:

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneCount() == 2) {
    // Dual sim
}
4
répondu oxied 2016-11-05 15:04:23

je suis capable de lire les deux IMEI de OnePlus 2 Téléphone

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                TelephonyManager manager = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
                Log.i(TAG, "Single or Dual Sim " + manager.getPhoneCount());
                Log.i(TAG, "Default device ID " + manager.getDeviceId());
                Log.i(TAG, "Single 1 " + manager.getDeviceId(0));
                Log.i(TAG, "Single 2 " + manager.getDeviceId(1));
            }
3
répondu Swapnil Godambe 2018-07-02 06:16:25

je jetais un oeil aux journaux d'appels et j'ai remarqué qu'en dehors des champs habituels dans le contenu de managedCursor, nous avons une colonne" simid " dans les téléphones SIM Dual (j'ai vérifié sur Xolo A500 Lite), de manière à marquer chaque appel dans le journal d'appels avec un SIM. Cette valeur est soit 1 ou 2, ce qui indique très probablement SIM1/SIM2.

managedCursor = context.getContentResolver().query(contacts, null, null, null, null);
managedCursor.moveToNext();        
for(int i=0;i<managedCursor.getColumnCount();i++)
{//for dual sim phones
    if(managedCursor.getColumnName(i).toLowerCase().equals("simid"))
        indexSIMID=i;
}

Je n'ai pas trouvé cette colonne dans un seul téléphone SIM (j'ai vérifié sur Xperia L).

donc bien que je ne pense pas que ce soit une façon infaillible de vérifier la double SIM nature, je le poste ici parce qu'il pourrait être utile à quelqu'un.

2
répondu zafar142003 2015-01-07 20:21:02

Conseils:

Vous pouvez essayer d'utiliser

ctx.getSystemService("phone_msim")

au lieu de

ctx.getSystemService(Context.TELEPHONY_SERVICE)

si vous avez déjà essayé la réponse de Vaibhav et telephony.getClass().getMethod() échoue, ci-dessus est ce qui fonctionne pour mon Qualcomm mobile.

1
répondu Bruce 2015-05-25 09:32:12
0
répondu gonzobrains 2017-05-23 11:33:26

j'ai trouvé ces propriétés de système sur Samsung S8

SystemProperties.getInt("ro.multisim.simslotcount", 1) > 1

aussi, selon la source: https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/com/android/internal/telephony/TelephonyProperties.java

getprop persist.radio.multisim.config renvoie " dsds " ou " dsda " sur la multi sim.

j'ai testé cela sur Samsung S8 et cela fonctionne

0
répondu kakopappa 2017-05-25 05:48:30