Après de nombreuses recherches sur les forums, je sais maintenant qu’il n’ya aucun moyen de trouver le numéro de série IMSI ou SIM des deux cartes SIM d’un téléphone à double carte SIM (sauf pour contacter le fabricant). Maintenant, ma question modifiée est la suivante: pouvons-nous détecter si le téléphone dispose de deux cartes SIM? Je crois que cela peut être détecté avec une certaine intelligence. Voici quelques façons dont je peux penser:
Composer un code USSD et rechercher les journaux pour le numéro IMEI (j'ai essayé avec * 139 # en Inde. Cela a fonctionné.) 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 Android et possède deux numéros IMEI.)
Enregistrement du numéro de série de la carte SIM et/ou de l’IMSI pour la carte SIM. Et après la détection de tout autre numéro de série/IMSI, même si le téléphone n’a pas été réinitialisé (c’est-à-dire si la carte SIM a été activée) en traçant certains journaux ou en gérant certains événements de diffusion.
En composant * 06 #, vous pourrez voir les deux numéros IMEI. D'une certaine manière, obtenez ces deux chiffres. (Quelque chose comme la capture d'écran et l'analyse d'images pour le texte.)
Si quelqu'un peut penser à d'autres moyens, ils sont les bienvenus. J'apprécierais vraiment toute sorte d'aide concernant ceci. De plus, si quelqu'un a des informations sur des API de fabricants ou des liens pour les contacter, veuillez les partager avec les membres de la communauté.
Mise à jour du 23 mars 2015:
Plusieurs API simultanées sont disponibles à partir d'Android 5.1
Autre option possible:
Vous pouvez utiliser Java réflexion pour obtenir les deux numéros IMEI.
En utilisant ces numéros IMEI, vous pouvez vérifier si le téléphone est une carte SIM DUAL 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);
}
}
}
Modifier :
L'accès à des méthodes telles que "getDeviceIdGemini" pour les détails d'un autre emplacement de carte SIM permet de prédire que cette méthode existe.
Si le nom de cette méthode ne correspond pas à celui donné par le fabricant du périphérique, cela ne fonctionnera pas. Vous devez trouver le nom de méthode correspondant à ces périphériques.
Vous pouvez rechercher les noms de méthodes d'autres fabricants 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();
}
}
MODIFIER :
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 la carte SIM de 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 s’applique à Lenovo A319 et aux autres téléphones de cette marque (Crédit Maher Abuthraa ):
telephonyInfo.imeiSIM1 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 0);
telephonyInfo.imeiSIM2 = getDeviceIdBySlot(context, "getSimSerialNumberGemini", 1);
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 (par exemple, appelez getDeviceIdDs) ne fonctionne pas pour moi, car cette 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 de manière itérative 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 try/catch. Par exemple, pour déterminer si nous avons deux cartes SIM actives, nous pourrions procéder comme suit:
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 à la matrice et cela devrait fonctionner.
J'ai trouvé plusieurs solutions natives lors de la recherche du moyen de vérifier l'opérateur de réseau.
Pour les 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 une autorisation:
<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 les 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 les API> = 23. Pour vérifier si le téléphone est dual/triple/many sim:
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneCount() == 2) {
// Dual sim
}
Je suis capable de lire les deux IMEI à partir de OnePlus 2 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));
}
J'examinais les journaux d'appels et j'ai remarqué que, mis à part les champs habituels du contenu de managedCursor, nous avons une colonne "simid" dans les téléphones Dual SIM (j'ai vérifié sur Xolo A500s Lite), afin de marquer chaque appel. dans le journal des appels avec une carte SIM. Cette valeur est 1 ou 2, dénotant 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 un moyen infaillible de vérifier la nature de la double carte SIM, je le publie ici car cela pourrait être utile à quelqu'un.
J'ai trouvé ces propriétés 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 multi sim.
J'ai testé cela sur Samsung S8 et cela fonctionne
Commonsware dit que ce n'est pas possible. Veuillez voir ce qui suit:
La détection de la double carte SIM à l'aide du SDK Android n'est pas possible.
Voici un autre dialogue sur le sujet: