Android: Periksa apakah ponsel memiliki SIM ganda

113

Setelah banyak riset di forum, sekarang saya tahu bahwa tidak ada cara untuk menemukan IMSI atau nomor seri SIM untuk kedua kartu SIM di ponsel SIM ganda (kecuali untuk menghubungi pabrikan). Sekarang pertanyaan saya yang berubah adalah, dapatkah kita sama sekali mendeteksi bahwa ponsel memiliki dua SIM? Saya yakin itu dapat dideteksi dengan kecerdasan tertentu. Beberapa cara yang bisa saya pikirkan adalah:

  1. Memanggil kode USSD dan menelusuri log untuk nomor IMEI (Saya mencoba ini dengan * 139 # di India. Berhasil.) Ini akan memberi saya nomor IMEI untuk SIM yang saya gunakan untuk memutar kode USSD. (Diasumsikan bahwa ponsel mengikuti pedoman Android dan memiliki dua nomor IMEI.)

  2. Menyimpan nomor seri SIM dan / atau IMSI untuk SIM tersebut. Dan setelah mendeteksi nomor IMSI / Serial lainnya bahkan jika telepon tidak di-boot ulang (yaitu SIM dialihkan) dengan melacak beberapa log atau dengan beberapa penanganan acara siaran.

  3. Dengan menekan * 06 # Anda akan melihat kedua nomor IMEI. Ngomong-ngomong, dapatkan kedua angka itu. (Sesuatu seperti pengambilan layar dan penguraian gambar untuk teks.)

Jika ada yang bisa memikirkan cara lain, mereka sangat disambut. Saya akan sangat menghargai bantuan apa pun terkait hal ini. Selain itu, jika ada yang memiliki informasi tentang API produsen atau tautan untuk menghubungi mereka, silakan bagikan dengan orang-orang komunitas.

Rajkiran
sumber
Hai Rajkiran, Akhirnya saya mendapatkan solusi yang berfungsi dengan baik untuk saya. Semoga bermanfaat bagi semua orang yang ingin menangani Duel SIM di aplikasi seluler. API pegangan SIM duel tidak didokumentasikan. Silakan periksa jawaban saya. Ini berfungsi dengan baik untuk saya. stackoverflow.com/questions/17618651/…
Jebasuthan
1
Terima kasih .. tapi jawaban Anda tidak menjawab pertanyaan saya. Saya ingin semua detail tentang SIM kedua dan IMEI. Jawaban @Pied Piper membantu saya mendapatkan segalanya.
Rajkiran
Jawaban @Rajkiran Pied Piper benar-benar membantu Anda? Saya telah memeriksa kodenya di m samsung galaxy y duos tetapi tidak berfungsi. Apakah Anda membantu saya menemukan nomor IMEI dari ponsel dual sim?
Nitish Patel
@ nitishpatel: Ya, pasti itu membantu. Sayangnya saya tidak memiliki Y Duos untuk diperiksa. Tapi saya yakin Samsung menggunakan mekanisme berbeda untuk penanganan SIM ganda pada Android versi 4.0 dan seterusnya. Jawaban Pied Pipers membantu di perangkat 4.0 dan seterusnya. Selebihnya, Anda perlu menggali lebih dalam menggunakan refleksi.
Rajkiran
Hai, Saya menemukan Solusi ... silakan periksa kode stackoverflow.com/a/32304799/3131373 Ini diuji pada berbagai ponsel
user3131373

Jawaban:

184

Pembaruan 23 Maret'15:

Beberapa API SIM resmi sekarang tersedia mulai Android 5.1 dan seterusnya

Opsi lain yang memungkinkan:

Anda dapat menggunakan refleksi Java untuk mendapatkan kedua nomor IMEI.

Dengan menggunakan nomor IMEI ini, Anda dapat memeriksa apakah ponsel itu SIM DUAL atau bukan.

Coba aktivitas berikut:

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

Dan ini dia 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:

Mendapatkan akses metode seperti "getDeviceIdGemini" untuk detail slot SIM lain memiliki prediksi bahwa metode tersebut ada.

Jika nama metode itu tidak cocok dengan yang diberikan oleh produsen perangkat maka itu tidak akan berfungsi. Anda harus menemukan nama metode yang sesuai untuk perangkat tersebut.

Menemukan nama metode untuk pabrikan lain dapat dilakukan dengan menggunakan refleksi Java sebagai berikut:

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:

Seperti yang ditunjukkan Seetha dalam komentarnya:

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

Ini berhasil untuknya. Dia berhasil mendapatkan dua nomor IMEI untuk kedua SIM di perangkat Samsung Duos.

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

EDIT 2:

Metode yang digunakan untuk mengambil data adalah untuk Lenovo A319 dan ponsel lain oleh pabrikan itu (Kredit Maher Abuthraa ):

telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 0); 
telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 1); 
Vaibhav Jani
sumber
4
Keren! Itu berhasil bagi saya dengan "getDeviceId" di Karbonn. Akan mencari metode Samsung dan akan memperbarui di sini ketika saya memilikinya. Terima kasih sobat. Pujian.
Rajkiran
1
Iya. Bahkan saya melakukan itu. Menemukan bahwa Samsung menggunakan secara com.android.internal.telephony.RILConstants$SimCardIDinternal. Bahkan mencoba membuat kelas itu dengan tanda tangan yang sama dari metode dan nama variabel yang sama. Tapi tidak beruntung. Akan mencoba mendapatkan kode sumber dan akan mencoba memeriksa. Terima kasih.
Rajkiran
4
Saya menggunakan telephonyInfo.imeiSIM1 = getDeviceIdBySlot (konteks, "getDeviceIdDs", 0); telephonyInfo.imeiSIM2 = getDeviceIdBySlot (konteks, "getDeviceIdDs", 1); Ini berhasil untuk saya. Saya berhasil mendapatkan dua nomor IMEI untuk kedua SIM tersebut.
Seetha
1
Bagaimana cara mendapatkan nomor telepon SIM2? Saya mendapatkan nomor SIM1 menggunakan metode telephony.getLine1Number (), dalam daftar metode saya tidak dapat menemukan metode seperti getLine2Number () atau getLine1Number (int)
DCoder
4
deviceId adalah IMEI bukan IMSI, bukan?
falko
5

Saya memiliki perangkat Samsung Duos dengan Android 4.4.4 dan metode yang disarankan oleh Seetha dalam jawaban yang diterima (yaitu panggilan getDeviceIdDs) tidak berfungsi untuk saya, karena metode tersebut tidak ada. Saya dapat memulihkan semua informasi yang saya butuhkan dengan memanggil metode "getDefault (int slotID)", seperti yang ditunjukkan di bawah ini:

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

Juga, saya menulis ulang kode yang secara iteratif menguji metode untuk memulihkan informasi ini sehingga menggunakan array nama metode alih-alih urutan coba / tangkap. Misalnya, untuk menentukan apakah kami memiliki dua SIM aktif, kami dapat melakukan:

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

Dengan cara ini, jika nama metode baru disarankan untuk beberapa perangkat, Anda cukup menambahkannya ke array dan itu akan berfungsi.

Eduardo Javier Huerta Yero
sumber
4

Ada beberapa solusi asli yang saya temukan saat mencari cara untuk memeriksa operator jaringan.

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

Di AndroidManifest, tambahkan izin:

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

Untuk mendapatkan operator jaringan, Anda dapat memeriksa kode mcc dan mnc:

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

Untuk API> = 23. Untuk sekadar memeriksa apakah ponsel dual / triple / banyak sim:

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

Saya dapat membaca kedua IMEI dari Telepon 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));
            }
Swapnil Godambe
sumber
Bagus itu berfungsi di One Plus. Tetapi meminta Anda untuk mengirim jawaban yang berfungsi untuk semua ponsel dan semua versi android (mungkin)
Rajkiran
1
Ini adalah SDK resmi. Harus berfungsi untuk semua ponsel. Saya telah mengujinya di OnePlus 2
Swapnil Godambe
Jadi, jawaban yang diterima dari @Swapnil menceritakan hal yang sama, bukan?
Rajkiran
2

Saya sedang melihat log panggilan dan saya perhatikan bahwa selain kolom biasa dalam konten managedCursor, kami memiliki kolom "simid" di ponsel Dual SIM (saya memeriksa Xolo A500s Lite), untuk menandai setiap panggilan di log panggilan dengan SIM. Nilai ini bisa 1 atau 2, kemungkinan besar menunjukkan 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;
}

Saya tidak menemukan kolom ini di satu telepon SIM (saya memeriksa Xperia L).

Jadi meskipun menurut saya ini bukan cara yang sangat mudah untuk memeriksa sifat SIM ganda, saya mempostingnya di sini karena itu bisa berguna bagi seseorang.

zafar142003
sumber
Anda sedang membaca DB, yang mana? Jelaskan apa yang Anda lakukan di sini. (Di mana db "kontak" disimpan?
not2qubit
1

Tips:

Anda bisa mencoba menggunakan

ctx.getSystemService("phone_msim")

dari pada

ctx.getSystemService(Context.TELEPHONY_SERVICE)

Jika Anda sudah mencoba jawaban Vaibhav dan telephony.getClass().getMethod()gagal, di atas adalah yang berfungsi untuk ponsel Qualcomm saya .

Bruce
sumber
Selama jawabannya lengkap, Anda dapat memposting tautan ke halaman web dalam bahasa lain untuk informasi tambahan. meta.stackoverflow.com/questions/271060/…
mach
Itu sebenarnya tautan yang berguna , tidak perlu menghapusnya.
not2qubit
0

Saya telah menemukan properti sistem ini di Samsung S8

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

Juga, menurut sumber: https://android.googlesource.com/platform/frameworks/base/+/master/telephony/java/com/android/internal/telephony/TelephonyProperties.java

getprop persist.radio.multisim.configmengembalikan " dsds" atau " dsda" pada multi sim.

Saya telah menguji ini di Samsung S8 dan berhasil

kakopappa.dll
sumber
Lupakan. Android sudah memiliki API untuk SIM ganda sekarang. developer.android.com/about/versions/android-5.1.html#multisim Untuk segala sesuatu yang lain, Anda bisa merujuk ke jawaban di atas oleh @vaibhav
Rajkiran
-1

Commonsware mengatakan ini tidak mungkin. Silakan lihat yang berikut ini:

Mendeteksi SIM Ganda menggunakan Android SDK tidak dimungkinkan.

Berikut dialog lebih lanjut tentang masalah ini:

Petugas tim pengembang Google mengatakan bahwa mendeteksi SIM Ganda menggunakan Android SDK tidak mungkin.

gonzobrains
sumber
3
Ya man. Saya tahu itu. Tapi itulah mengapa saya mencoba mencari solusi. Dan harus ada beberapa. Coba aplikasi USSDDualWidget dari Play Store. Ini sebenarnya dapat beralih di antara dua SIM. Bahkan mencoba merekayasa balik kode tersebut, tetapi tidak berhasil.
Rajkiran
Apakah ini berfungsi pada semua perangkat atau hanya sebagian terbatas yang mengekspos semacam antarmuka berpemilik?
Gonzobrains
2
Mengapa jawaban ini tidak disukai? Ini jawaban yang benar. ^
N Sharma
24
Banyak kali commonsware mengatakan itu tidak mungkin yang dimungkinkan oleh pengembang lain. Jadi, tidak seperti itu yang dikatakan commonsware selalu benar :-)
Lalit Poptani
1
Anda mungkin benar, tetapi menurut saya dia adalah sumber yang cukup kredibel untuk semua hal Android. Adapun masalah khusus ini, tentu, saya melakukan hal yang sama dan menggunakan refleksi untuk mendapatkan data sim ganda, tetapi itu untuk perangkat khusus saya. Sampai hari ini, saya masih tidak percaya ada cara umum untuk melakukan ini. Juga perhatikan saya mengutip pengembang Google juga dan bukan hanya Commonsware.
gonzobrains