Android: Überprüfen Sie, ob das Telefon Dual-SIM ist


113

Nach vielen Recherchen in Foren weiß ich jetzt, dass es keine Möglichkeit gibt, die IMSI- oder SIM-Seriennummer für beide SIM-Karten in einem Dual-SIM-Telefon zu finden (außer bei der Kontaktaufnahme mit dem Hersteller). Meine geänderte Frage lautet nun: Können wir überhaupt feststellen, dass das Telefon zwei SIM-Karten hat? Ich glaube, dass es mit etwas Intelligenz entdeckt werden kann. Ich kann mir nur wenige Möglichkeiten vorstellen:

  1. Wählen eines USSD-Codes und Verfolgen der Protokolle für die IMEI-Nummer (Ich habe dies mit * 139 # in Indien versucht. Es hat funktioniert.) Dadurch erhält ich die IMEI-Nummer für die SIM-Karte, von der aus ich den USSD-Code gewählt habe. (Es wird davon ausgegangen, dass das Telefon den Android-Richtlinien entspricht und zwei IMEI-Nummern hat.)

  2. Speichern der SIM-Seriennummer und / oder der IMSI für die SIM. Und nach dem Erkennen einer anderen IMSI- / Seriennummer, auch wenn das Telefon nicht neu gestartet wurde (dh die SIM-Karte wurde umgeschaltet), indem einige Protokolle verfolgt oder ein Broadcast-Ereignis behandelt wurde.

  3. Wenn Sie * 06 # wählen, werden beide IMEI-Nummern angezeigt. Erhalten Sie auf irgendeine Weise diese beiden Zahlen. (So ​​etwas wie Bildschirmaufnahme und Bildanalyse für Text.)

Wenn sich jemand andere Möglichkeiten vorstellen kann, sind sie herzlich willkommen. Ich würde mich über jede Hilfe in dieser Hinsicht sehr freuen. Wenn jemand Informationen über Hersteller-APIs oder Links hat, um diese zu kontaktieren, teilen Sie diese bitte mit den Community-Leuten.


Hallo Rajkiran, endlich habe ich die Lösung, die für mich gut funktioniert. Ich hoffe, es sollte für alle hilfreich sein, die mit Duel SIM in mobilen Anwendungen umgehen möchten. Die Duell-SIM-Handle-API ist nicht dokumentiert. Bitte überprüfen Sie meine Antwort, es funktioniert gut für mich. stackoverflow.com/questions/17618651/…
Jebasuthan

1
Danke .. aber deine Antwort beantwortet meine Frage nicht. Ich möchte alle Details über die zweite SIM und IMEI. Die Antwort von @Pied Piper hilft mir, alles zu bekommen.
Rajkiran

@ Rajkiran Rattenfänger Antwort hat dir wirklich geholfen? Ich habe seinen Code in Samsung Galaxy Y Duos überprüft, aber es funktioniert nicht. Haben Sie mir geholfen, IMEI-Nummern von Dual-SIM-Telefonen zu finden?
Nitish Patel

@nitishpatel: Ja auf jeden Fall hat es geholfen. Leider habe ich Y Duos nicht zu überprüfen. Ich glaube jedoch, dass Samsung ab Android Version 4.0 einen anderen Mechanismus für die Dual-SIM-Handhabung verwendet. Pied Pipers Antwort hilft bei Geräten ab 4.0. Im Übrigen müssen Sie mit Reflexion etwas mehr graben.
Rajkiran

Hallo, ich finde eine Lösung ... bitte überprüfen Sie den Code stackoverflow.com/a/32304799/3131373 Es wird auf verschiedenen Telefonen getestet
user3131373

Antworten:


184

Update 23. März 15:

Die offizielle Mehrfach-SIM-API ist ab Android 5.1 verfügbar

Andere mögliche Option:

Sie können Java Reflection verwenden , um beide IMEI-Nummern abzurufen.

Mit diesen IMEI-Nummern können Sie überprüfen, ob das Telefon eine DUAL SIM ist oder nicht.

Versuchen Sie folgende Aktivität:

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

Und hier ist 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);
        }
    }
}

Bearbeiten:

Wenn Sie auf Methoden wie "getDeviceIdGemini" für die Details anderer SIM-Steckplätze zugreifen, wird vorausgesagt, dass diese Methode vorhanden ist.

Wenn der Name dieser Methode nicht mit dem Namen des Geräteherstellers übereinstimmt, funktioniert er nicht. Sie müssen den entsprechenden Methodennamen für diese Geräte finden.

Das Finden von Methodennamen für andere Hersteller kann mithilfe von Java Reflection wie folgt erfolgen:

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:

Wie Seetha in ihrem Kommentar betonte:

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

Es funktioniert für sie. Es gelang ihr, zwei IMEI-Nummern für beide SIM-Karten im Samsung Duos-Gerät zu erhalten.

Hinzufügen <uses-permission android:name="android.permission.READ_PHONE_STATE" />

EDIT 2:

Die Methode zum Abrufen von Daten gilt für Lenovo A319 und andere Telefone dieses Herstellers (Credit Maher Abuthraa ):

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

4
Cool! Das hat bei mir mit "getDeviceId" auf Karbonn funktioniert. Sucht nach Samsung-Methoden und wird hier aktualisiert, wenn ich sie bei mir habe. Danke, Mann. Ein großes Lob.
Rajkiran

1
Ja. Sogar ich habe das getan. Gefunden, dass Samsung com.android.internal.telephony.RILConstants$SimCardIDintern verwendet. Es wurde sogar versucht, diese Klasse mit derselben Methodensignatur und denselben Variablennamen zu erstellen. Aber kein Glück. Wird versuchen, den Quellcode zu erhalten und wird versuchen, dies zu überprüfen. Vielen Dank.
Rajkiran

4
Ich verwende telephonyInfo.imeiSIM1 = getDeviceIdBySlot (Kontext "getDeviceIdDs", 0); telephonyInfo.imeiSIM2 = getDeviceIdBySlot (Kontext "getDeviceIdDs", 1); Es funktioniert für mich. Es ist mir gelungen, zwei IMEI-Nummern für beide SIM-Karten zu erhalten.
Seetha

1
Wie kann ich die Telefonnummer von SIM2 erhalten? Ich erhalte die SIM1-Nummer mit der Methode telephony.getLine1Number (). In der Liste der Methoden kann ich keine Methode wie getLine2Number () oder getLine1Number (int) finden
DCoder

4
deviceId ist IMEI nicht IMSI, nicht wahr?
Falko

5

Ich habe ein Samsung Duos-Gerät mit Android 4.4.4 und die von Seetha in der akzeptierten Antwort vorgeschlagene Methode (z. B. getDeviceIdDs aufrufen) funktioniert bei mir nicht, da die Methode nicht vorhanden ist. Ich konnte alle benötigten Informationen wiederherstellen, indem ich die Methode "getDefault (int slotID)" aufrief, wie unten gezeigt:

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

Außerdem habe ich den Code neu geschrieben, der iterativ nach Methoden zum Wiederherstellen dieser Informationen testet, sodass anstelle einer Folge von try / catch ein Array von Methodennamen verwendet wird. Um beispielsweise festzustellen, ob wir zwei aktive SIM-Karten haben, können wir Folgendes tun:

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

Auf diese Weise können Sie, wenn für ein Gerät ein neuer Methodenname vorgeschlagen wird, diesen einfach zum Array hinzufügen, und es sollte funktionieren.


4

Es gibt mehrere native Lösungen, die ich gefunden habe, als ich nach einer Möglichkeit gesucht habe, den Netzbetreiber zu überprüfen.

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

Fügen Sie in AndroidManifest die Berechtigung hinzu:

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

Um den Netzbetreiber zu erhalten, können Sie die Codes mcc und mnc überprüfen:

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

Für API> = 23. Um zu überprüfen, ob das Telefon Dual / Triple / Many Sim ist:

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

4

Ich kann beide IMEIs von OnePlus 2 Phone lesen

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

Gut, dass es auf One Plus funktioniert. Aber fordern Sie Sie auf, Antworten zu posten, die für alle Telefone und alle Android-Versionen (wahrscheinlich)
funktionieren

1
Dies ist ein offizielles SDK. Sollte für alle Telefone funktionieren. Ich habe es auf OnePlus 2
Swapnil Godambe

Die akzeptierte Antwort von @Swapnil sagt also dasselbe aus, oder?
Rajkiran

2

Ich habe mir die Anrufprotokolle angesehen und festgestellt, dass wir in Dual-SIM-Telefonen (ich habe Xolo A500s Lite überprüft) neben den üblichen Feldern im Inhalt von manageCursor eine Spalte "simid" haben, um jeden Anruf zu kennzeichnen im Anrufprotokoll mit einer SIM. Dieser Wert ist entweder 1 oder 2, was höchstwahrscheinlich SIM1 / SIM2 bedeutet.

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

Ich habe diese Spalte in keinem einzelnen SIM-Telefon gefunden (ich habe das Xperia L überprüft).

Obwohl ich nicht denke, dass dies eine narrensichere Möglichkeit ist, die Dual-SIM-Natur zu überprüfen, poste ich sie hier, weil sie für jemanden nützlich sein könnte.


Sie lesen eine DB, welche? Bitte klären Sie, was Sie hier tun. (Wo ist die "Kontakte"
Datenbank

1

Tipps:

Sie können versuchen, zu verwenden

ctx.getSystemService("phone_msim")

anstatt

ctx.getSystemService(Context.TELEPHONY_SERVICE)

Wenn Sie Vaibhavs Antwort bereits ausprobiert haben und telephony.getClass().getMethod()fehlschlagen, funktioniert dies oben für mein Qualcomm- Handy.


Solange die Antwort vollständig ist , können Sie Links zu Webseiten in anderen Sprachen veröffentlichen, um zusätzliche Informationen zu erhalten. meta.stackoverflow.com/questions/271060/…
mach

Das war eigentlich ein nützlicher Link , der nicht entfernt werden musste.
not2qubit

0

Ich habe diese Systemeigenschaften auf Samsung S8 gefunden

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

Laut Quelle: https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/com/android/internal/telephony/TelephonyProperties.java

getprop persist.radio.multisim.configgibt " dsds" oder " dsda" auf Multi-Sim zurück.

Ich habe dies auf Samsung S8 getestet und es funktioniert


Keine Ursache. Android hat bereits APIs für Dual-SIM. developer.android.com/about/versions/android-5.1.html#multisim Für alles andere können Sie sich auf die obige Antwort von @vaibhav
Rajkiran

-1

Commonsware sagt, dass dies nicht möglich ist. Bitte beachten Sie Folgendes:

Das Erkennen von Dual-SIM mit Android SDK ist nicht möglich.

Hier ist ein weiterer Dialog zum Thema:

Der Entwickler von Google sagt, dass das Erkennen von Dual-SIM-Karten mit dem Android SDK nicht möglich ist.


3
Ja Mann. Ich weiß das. Aber deshalb versuche ich, eine Problemumgehung zu finden. Und es muss welche geben. Probieren Sie die USSDDualWidget-App aus dem Play Store aus. Es kann tatsächlich zwischen den beiden SIM-Karten wechseln. Ich habe sogar versucht, den Code zurückzuentwickeln, aber kein Glück.
Rajkiran

Funktioniert es auf allen Geräten oder nur auf einer begrenzten Teilmenge, die eine proprietäre Schnittstelle verfügbar macht?
Gonzobrains

2
Warum wurde diese Antwort abgelehnt? Das ist die richtige Antwort. ^
N Sharma

24
Viele Male hat Commonsware gesagt, dass dies nicht möglich ist, was von anderen Entwicklern ermöglicht wurde. Also, es ist nicht so, was Commonsware sagt, ist immer richtig :-)
Lalit Poptani

1
Sie mögen Recht haben, aber ich denke, er ist eine ziemlich glaubwürdige Ressource für alles, was mit Android zu tun hat. Was dieses spezielle Problem betrifft, habe ich das Gleiche getan und Reflexion verwendet, um Dual-Sim-Daten zu erhalten, aber es war für mein spezielles Gerät. Bis heute glaube ich nicht, dass es einen generischen Weg gibt, dies zu tun. Beachten Sie auch, dass ich auch einen Google-Entwickler zitiert habe und nicht nur Commonsware.
Gonzobrains
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.