Android: Telefonun çift SIM olup olmadığını kontrol edin


113

Forumlarda yapılan birçok araştırmadan sonra, artık çift SIM kartlı bir telefonda her iki SIM kart için de IMSI veya SIM seri numarası bulmanın bir yolu olmadığını biliyorum (üreticiyle iletişim kurmak dışında). Şimdi değiştirdiğim sorum, telefonun iki SIM'e sahip olduğunu tespit edebilir miyiz? Biraz zeka ile tespit edilebileceğine inanıyorum. Düşünebileceğim birkaç yol:

  1. Bir USSD kodunu çevirmek ve IMEI numarası için günlükleri izlemek (Bunu Hindistan'da * 139 # ile denedim. Çalıştı.) Bu bana USSD kodunu çevirdiğim SIM için IMEI numarasını verecektir. (Telefonun android yönergelerini izlediği ve iki IMEI numarasına sahip olduğu varsayılmaktadır.)

  2. SIM için SIM seri numarasını ve / veya IMSI'yi kaydetme. Ve başka bir IMSI / Seri numarasının tespit edilmesinden sonra, telefon yeniden başlatılmamış olsa bile (yani SIM değiştirilmişse), bazı günlüklerin izlenmesi veya bazı yayın olaylarının işlenmesi ile.

  3. * 06 # tuşlayarak her iki IMEI numarasını da göreceksiniz. Bir şekilde, şu iki sayıyı alın. (Ekran yakalama ve metin için görüntü ayrıştırma gibi bir şey.)

Herhangi biri başka yollar düşünebilirse, çok hoş karşılanırlar. Bununla ilgili her türlü yardıma gerçekten minnettar olurum. Ayrıca, herhangi bir üreticinin API'leri hakkında herhangi bir bilgisi veya bunlarla bağlantı kurmak için herhangi bir bağlantı varsa, lütfen topluluktaki kişilerle paylaşın.


Merhaba Rajkiran, Sonunda çözümü benim için iyi çalışıyor. Düello SIM'i mobil uygulamalarda kullanmak isteyen herkese yardımcı olacağını umuyoruz. Düello SIM tutamaç API'si belgelenmemiştir. Lütfen cevabımı kontrol edin, benim için iyi çalışıyor. stackoverflow.com/questions/17618651/…
Jebasuthan

1
Teşekkürler .. ama cevabınız soruma cevap vermiyor. İkinci SIM ve IMEI ile ilgili tüm detayları istiyorum. @Pied Piper'ın cevabı her şeyi almama yardımcı oluyor.
Rajkiran

@Rajkiran Pied Piper'in cevabı gerçekten size yardımcı oldu mu? Onun kodunu m samsung galaxy y duos'ta kontrol ettim ama çalışmıyor. Çift sim telefonun IMEI numaralarını bulmama yardım ettin mi?
Nitish Patel

@nitishpatel: Evet kesinlikle yardımcı oldu. Maalesef kontrol etmem gereken Y Duo'm yok. Ancak Samsung'un Android 4.0 sürümünden itibaren çift SIM kullanımı için farklı bir mekanizma kullandığına inanıyorum. Pied Pipers cevabı, 4.0 sonrası cihazlarda yardımcı olur. Geri kalanı için, yansımayı kullanarak biraz daha kazmanız gerekecek.
Rajkiran

Merhaba, bir Çözüm buldum ... lütfen stackoverflow.com/a/32304799/3131373 kodunu kontrol edin Çeşitli telefonlarda test edildi
user3131373

Yanıtlar:


184

23 Mart'15 Güncellemesi:

Resmi çoklu SIM API artık Android 5.1'den itibaren mevcuttur

Diğer olası seçenek:

Her iki IMEI numarasını almak için Java yansımasını kullanabilirsiniz .

Bu IMEI numaralarını kullanarak telefonun ÇİFT SIM olup olmadığını kontrol edebilirsiniz.

Aşağıdaki etkinliği deneyin:

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

Ve işte 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);
        }
    }
}

Düzenle :

Diğer SIM yuvasının ayrıntısı için "getDeviceIdGemini" gibi yöntemlere erişim elde etmek, yöntemin var olduğunu tahmin eder.

Bu yöntemin adı, cihaz üreticisi tarafından verilenle eşleşmezse, işe yaramayacaktır. Bu cihazlar için uygun yöntem adını bulmanız gerekir.

Diğer üreticiler için yöntem adlarının bulunması, aşağıdaki gibi Java yansıması kullanılarak yapılabilir:

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

DÜZENLE :

Seetha'nın yorumunda işaret ettiği gibi :

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

Onun için çalışıyor. Samsung Duos cihazında her iki SIM için iki IMEI numarası almayı başardı.

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

DÜZENLEME 2:

Veri almak için kullanılan yöntem, Lenovo A319 ve bu üreticinin diğer telefonları içindir (Credit Maher Abuthraa ):

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

4
Güzel! Bu benim için Karbonn'daki "getDeviceId" ile çalıştı. Samsung yöntemlerini arayacak ve yanımda olduğunda burada güncellenecek. Teşekkürler dostum. Kudos.
Rajkiran

1
Evet. Ben bile yaptım. Samsung'un com.android.internal.telephony.RILConstants$SimCardIDdahili olarak kullandığı bulundu . Hatta bu sınıfı aynı yöntem imzası ve aynı değişken adlarıyla oluşturmayı denedim. Ama şans yok. Kaynak kodunu almayı deneyecek ve kontrol etmeye çalışacak. Teşekkürler.
Rajkiran

4
TelephonyInfo.imeiSIM1 = getDeviceIdBySlot (bağlam, "getDeviceIdDs", 0); telephonyInfo.imeiSIM2 = getDeviceIdBySlot (bağlam, "getDeviceIdDs", 1); Benim için çalışıyor. Her iki SIM için de iki IMEI numarası almayı başardım.
Seetha

1
SIM2'nin Telefon numarasını nasıl alabilirim? Telephony.getLine1Number () yöntemini kullanarak SIM1 numarası alıyorum, yöntem listesinde getLine2Number () veya getLine1Number (int) gibi bir yöntem bulamıyorum
DCoder

4
deviceId, IMEI, IMSI değil, değil mi?
falko

5

Android 4.4.4'e sahip bir Samsung Duos cihazım var ve kabul edilen yanıtta Seetha tarafından önerilen yöntem (yani getDeviceIdDs çağrısı) yöntem mevcut olmadığından benim için çalışmıyor. İhtiyacım olan tüm bilgileri aşağıda gösterildiği gibi "getDefault (int slotID)" yöntemini çağırarak kurtarabildim:

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

Ayrıca, bu bilgiyi kurtarmak için yöntemleri yinelemeli olarak test eden kodu yeniden yazdım, böylece bir dene / yakala dizisi yerine yöntem adları dizisi kullanır. Örneğin, iki aktif SIM'iniz olup olmadığını belirlemek için yapabiliriz:

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

Bu şekilde, bazı aygıtlar için yeni bir yöntem adı önerilirse, bunu diziye ekleyebilirsiniz ve çalışmalıdır.


4

Şebeke operatörünü kontrol etmenin yolunu ararken bulduğum birkaç yerel çözüm var.

API> = 17 için:

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

AndroidManifest'te ekleme izni:

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

Şebeke operatörünü almak için mcc ve mnc kodlarını kontrol edebilirsiniz:

API> = 22 için:

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> = 23 için. Telefonun çift / üçlü / çok sim olup olmadığını kontrol etmek için:

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

4

Her iki IMEI'yi de OnePlus 2 Telefonundan okuyabiliyorum

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

One Plus'ta çalışması güzel. Ancak sizden tüm telefonlarda ve tüm android sürümlerinde (muhtemelen) çalışan cevaplar göndermenizi rica ediyoruz
Rajkiran

1
Bu resmi bir SDK'dır. Tüm telefon için çalışmalıdır. OnePlus 2'de test ettim
Swapnil Godambe

Yani @ Swapnil'den kabul edilen cevap aynı şeyi söylüyor değil mi?
Rajkiran

2

Arama günlüklerine bir göz atıyordum ve managedCursor içeriğindeki olağan alanlardan ayrı olarak, her aramayı etiketlemek için Çift SIM telefonlarda (Xolo A500s Lite üzerinde kontrol ettim) bir "simid" sütunumuz olduğunu fark ettim. SIM ile arama kaydında. Bu değer 1 veya 2'dir ve büyük olasılıkla SIM1 / SIM2'yi ifade eder.

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

Bu sütunu tek bir SIM telefonda bulamadım (Xperia L'de kontrol ettim).

Bu yüzden, bunun çift SIM niteliğini kontrol etmenin kusursuz bir yolu olduğunu düşünmesem de, buraya gönderiyorum çünkü birisi için yararlı olabilir.


Bir DB okuyorsunuz, hangisi? Lütfen burada ne yaptığınızı netleştirin. ("Kişiler" veritabanı nerede saklanır?
not2qubit

1

İpuçları:

Kullanmayı deneyebilirsin

ctx.getSystemService("phone_msim")

onun yerine

ctx.getSystemService(Context.TELEPHONY_SERVICE)

Vaibhav'ın cevabını zaten denediyseniz ve telephony.getClass().getMethod()başarısız olursa, yukarıda Qualcomm cep telefonum için işe yarayan şey budur .


Cevap tamamlandığı sürece, ek bilgiler için diğer dillerdeki web sayfalarına bağlantılar gönderebilirsiniz. meta.stackoverflow.com/questions/271060/…
mach

Bu aslında faydalı bir bağlantıydı , kaldırmaya gerek yok.
not2qubit

0

Bu sistem özelliklerini Samsung S8'de buldum

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

Ayrıca kaynağa göre: https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/com/android/internal/telephony/TelephonyProperties.java

getprop persist.radio.multisim.configçoklu simde " dsds" veya " dsda" döndürür .

Bunu Samsung S8'de test ettim ve çalışıyor


Boşver. Android'in artık çift SIM için API'leri var. developer.android.com/about/versions/android-5.1.html#multisim Diğer her şey için yukarıdaki cevaba @vaibhav
Rajkiran

-1

Commonsware bunun mümkün olmadığını söylüyor. Lütfen aşağıdakilere bakın:

Çift SIM'i Android SDK kullanarak tespit etmek mümkün değildir.

İşte konuyla ilgili daha fazla diyalog:

Google geliştirici ekip üyesi, Android SDK kullanarak Çift SIM algılamanın mümkün olmadığını söylüyor.


3
Evet adamım. Bunu biliyorum. Ama bu yüzden bir çözüm bulmaya çalışıyorum. Ve biraz olmalı. Play Store'dan USSDDualWidget uygulamasını deneyin. Aslında iki SIM arasında geçiş yapabilir. Kodu tersine çevirmeye bile çalıştım ama şans yok.
Rajkiran

Tüm cihazlarda mı yoksa bir tür tescilli arayüzü ortaya çıkaran sınırlı bir alt kümede mi çalışıyor?
gonzobrains

2
Bu yanıt neden reddedildi? Bu doğru cevap. ^
N Sharma

24
Çoğu zaman ortak yazılım, diğer geliştiriciler tarafından mümkün olanın mümkün olmadığını söyledi . Yani, ortak yazılımın söylediği gibi değil :-)
Lalit Poptani

1
Haklı olabilirsiniz, ancak Android ile ilgili her şey için oldukça güvenilir bir kaynak olduğunu düşünüyorum. Bu özel konuya gelince, elbette, aynı şeyi yaptım ve çift sim verisi elde etmek için yansımayı kullandım, ancak bu benim özel cihazım içindi. Bugüne kadar, bunu yapmanın genel bir yolu olduğuna hala inanmıyorum. Ayrıca yalnızca Commonsware'den değil, bir Google geliştiricisinden de alıntı yaptığımı fark ettim.
gonzobrains
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.