115 votes

Android : Vérifiez si le téléphone est doté d'une double carte SIM

Après de nombreuses recherches sur les forums, je sais maintenant qu'il n'y a aucun moyen de trouver l'IMSI ou le numéro de série de la carte SIM pour les deux cartes SIM d'un téléphone à double SIM (sauf à contacter le fabricant). Maintenant, ma nouvelle question est la suivante : peut-on détecter que le téléphone a deux cartes SIM ? Je pense que cela peut être détecté avec un peu d'intelligence. Voici quelques moyens auxquels je pense :

  1. Composer un code USSD et rechercher le numéro IMEI dans les journaux (j'ai essayé avec *139# en Inde. Ça a marché.) Cela me donnera le numéro IMEI de la carte SIM à partir de laquelle j'ai composé le code USSD. (On suppose que le téléphone suit les directives d'Android et a deux numéros IMEI).

  2. Stocker le numéro de série et/ou l'IMSI de la carte SIM. Et après la détection de tout autre IMSI/Numéro de série, même si le téléphone n'a pas été redémarré (c'est-à-dire que la carte SIM a été changée), en traçant certains journaux ou en traitant certains événements de diffusion.

  3. En composant *06#, vous obtiendrez les deux numéros IMEI. Par un moyen quelconque, obtenez ces deux numéros. (Quelque chose comme la capture d'écran et l'analyse d'image pour le texte).

Si quelqu'un peut penser à d'autres moyens, il est le bienvenu. J'apprécierais vraiment toute forme d'aide à ce sujet. De même, si quelqu'un a des informations sur les API des fabricants ou des liens pour les contacter, merci de les partager avec les membres de la communauté.

0 votes

Salut Rajkiran, enfin j'ai obtenu la solution son travail bien pour moi. J'espère qu'il devrait être utile pour tous ceux qui veulent gérer Duel SIM dans les applications mobiles. Le duel SIM handle API n'est pas documenté. S'il vous plaît vérifier ma réponse son travail bien pour moi. stackoverflow.com/questions/17618651/

1 votes

Merci mais votre réponse ne répond pas à ma question. Je veux tous les détails sur la deuxième SIM et l'IMEI. La réponse de @Pied Piper m'aide à tout obtenir.

0 votes

@Rajkiran La réponse de Pied Piper vous a vraiment aidé ? J'ai vérifié son code dans mon Samsung Galaxy Y Duos mais cela ne fonctionne pas, m'avez-vous aidé à trouver les numéros IMEI des téléphones double sim ?

188voto

Pied Piper Points 5554

Mise à jour 23 mars '15 :

L'API officielle pour les cartes SIM multiples est disponible à partir d'Android 5.1.

Autre option possible :

Vous pouvez utiliser Réflexion Java pour obtenir les deux numéros IMEI.

En utilisant ces numéros IMEI, vous pouvez vérifier si le téléphone est une DUAL SIM ou non.

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 :

L'accès à des méthodes comme "getDeviceIdGemini" pour le détail d'un autre emplacement SIM a permis de prédire l'existence de cette méthode.

Si le nom de cette méthode ne correspond pas à celui donné par le fabricant de l'appareil, elle ne fonctionnera pas. Vous devez trouver le nom de la méthode correspondante pour ces appareils.

La recherche de noms de méthodes pour d'autres fabricants peut être effectuée en utilisant la réflexion Java 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); 

Cela fonctionne pour elle. Elle a réussi à obtenir deux numéros IMEI pour les deux SIM de l'appareil Samsung Duos.

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

EDIT 2 :

La méthode utilisée pour récupérer les données concerne le Lenovo A319 et d'autres téléphones de cette marque (Crédit photo : ). Maher Abuthraa ) :

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

4 votes

Cool ! Cela a fonctionné pour moi avec "getDeviceId" sur Karbonn. Je vais chercher les méthodes de Samsung et je mettrai à jour ici quand je l'aurai avec moi. Merci mec. Kudos.

0 votes

J'ai réussi à obtenir les numéros IMSI pour les deux cartes SIM des téléphones Karbonn. J'ai beaucoup essayé d'obtenir 2 numéros IMEI ou des informations sur les deux cartes SIM pour les téléphones Karbonn. Samsung . Mais d'une manière ou d'une autre I couldn't . Pouvez-vous vérifier sur les téléphones Samsung à double SIM et nous le faire savoir ? Si possible, veuillez me contacter via mon profil.

0 votes

Malheureusement, je n'ai pas trouvé de méthode directe déclarée pour obtenir le second IMEI en imprimant la liste des méthodes de la classe de téléphonie dans les appareils Samsung, donc je ne trouve pas non plus d'indice pour une autre méthode. Si j'obtiens cela, je mettrai sûrement à jour ici.

6voto

oxied Points 121

Il y a plusieurs solutions natives que j'ai trouvées en cherchant le moyen 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, ajoutez la permission :

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

Pour obtenir un 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 simplement si le téléphone a une double/triple/multiples sim :

TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneCount() == 2) {
    // Dual sim
}

5voto

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 (c'est-à-dire appeler getDeviceIdDs) ne fonctionne pas pour moi, car 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 indiqué ci-dessous :

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

De plus, j'ai réécrit le code qui teste itérativement les méthodes pour récupérer ces informations afin qu'il utilise un tableau de noms de méthodes au lieu d'une séquence de try/catch. Par exemple, pour déterminer si nous avons deux SIMs 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;
}

Ainsi, si un nouveau nom de méthode est suggéré pour un dispositif, il suffit de l'ajouter au tableau pour qu'il fonctionne.

5voto

Swapnil Godambe Points 816

Je suis capable de lire les deux IMEI du téléphone OnePlus 2.

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

0 votes

C'est bien que ça marche sur le One Plus. Mais je vous demande de poster des réponses qui fonctionnent pour tous les téléphones et toutes les versions d'Android (probablement).

1 votes

Il s'agit d'un SDK officiel. Il devrait fonctionner sur tous les téléphones. Je l'ai testé sur OnePlus 2

0 votes

La réponse acceptée de @Swapnil dit donc la même chose, n'est-ce pas ?

2voto

zafar142003 Points 30

Je regardais les journaux d'appels et j'ai remarqué qu'en plus des champs habituels dans le contenu de managedCursor, nous avons une colonne "simid" dans les téléphones à double SIM (j'ai vérifié sur le Xolo A500s Lite), afin de marquer chaque appel dans le journal d'appels avec une SIM. Cette valeur est soit 1 soit 2, désignant 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 téléphone mono SIM (j'ai vérifié sur le Xperia L).

Ainsi, bien que je ne pense pas que ce soit un moyen infaillible de vérifier la nature de la double SIM, je le publie ici car il pourrait être utile à quelqu'un.

0 votes

Vous lisez un DB, lequel ? Veuillez clarifier ce que vous faites ici. (Où est stockée la base de données "contacts" ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X