隨意切換雙卡流量,立即獲取對應卡的SMIS


 原生的Android是不支持雙卡雙待功能的,所以Android sdk沒有提供API,直到在Android6.0+上增加了相關的API,但是國內的android的情況嘛,大家都懂得,有6.0和沒6.0沒啥區別, 因為基本各大廠商都已經更改底層系統了;

所以小編費了九牛二虎之力,依然沒有在網上找到對應的解決辦法,那怎么辦????分析源碼吧,呵呵!現解決辦法,希望對小伙伴沒有幫助!

直接上代碼:

主要有下面三個方法:

1:先判斷當前手機是否打開本地流量

2:再判斷當前哪張卡走流量,然后獲取對應卡的卡槽

3:再根據對應的卡槽獲取subid  然后獲取IMSI

//1: 判斷數據流量開關是否打開
public static boolean isMobileEnabled(Context context) {
try {
Method getMobileDataEnabledMethod =
ConnectivityManager.class.getDeclaredMethod("getMobileDataEnabled");
getMobileDataEnabledMethod.setAccessible(true);
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

boolean b = (boolean) getMobileDataEnabledMethod.invoke(connectivityManager);
;
return b;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return true;
}
//2:TODO 判斷當前那張卡 是走流量的
@SuppressLint("MissingPermission")
public static Integer getDefaultDataSubId(Context context) {
Integer id = -1;
try {
SubscriptionManager sm = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
sm = SubscriptionManager.from(context.getApplicationContext());
Method getSubId = sm.getClass().getMethod("getDefaultDataSubId");
if (getSubId != null) {
id = (int) getSubId.invoke(sm);
}
}
} catch (NoSuchMethodException e) {
try {
SubscriptionManager sm = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
sm = SubscriptionManager.from(context.getApplicationContext());
Method getSubId = sm.getClass().getMethod("getDefaultDataSubscrptionId");
if (getSubId != null) {
id = (int) getSubId.invoke(sm);
}
}
} catch (NoSuchMethodException e1) {
//
try {
SubscriptionManager sm = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
sm = SubscriptionManager.from(context.getApplicationContext());
Method getSubId = sm.getClass().getMethod("getDefaultDataPhoneId");
// Method getSubId = Class.forName("android.telephony.SubscriptionManager").getDeclaredMethod("getSubId", new Class[]{Integer.TYPE});
if (getSubId != null) {
id = (int) getSubId.invoke(sm);
Log.v("GetPhoneInfoHelper", (int) getSubId.invoke(sm) + "");
}
}
} catch (NoSuchMethodException e2) {
e.printStackTrace();
} catch (IllegalAccessException e2) {
e.printStackTrace();
} catch (InvocationTargetException e2) {
e.printStackTrace();
}
} catch (IllegalAccessException e1) {
e.printStackTrace();
} catch (InvocationTargetException e1) {
e.printStackTrace();
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return id;

}
//3:TODO  獲取雙卡雙待  卡序列號
public static String getSubscriberId(Context context, TelephonyManager telephony,int simSlotIndex) {
Class<?> telephonyClass;
String rtResult = null;
try {
telephonyClass = Class.forName(telephony.getClass().getName());
Method method = telephonyClass.getMethod("getSubscriberId", new Class[]{int.class});
rtResult = (String) method.invoke(telephony,simSlotIndex);
} catch (Exception e) {
e.printStackTrace();
}
return rtResult;
}


代碼調用:
String IMSI =  ReflectionGetCard.getSubscriberId(context,tm,ReflectionGetCard.getDefaultDataSubId(context)); 
注意:我調用沒有判斷 當前 是否打開本地流量 ,因為我只需要獲取對應卡的網絡狀態等;這個ReflectionGetCard類是上面方法的封裝類;
親測:紅米、oppoR11S、華為榮耀8是正常的獲取的;
PS:在華為榮耀8上 上面調用代碼需要更改一下:
String IMSI = tm.getSubscriberId();

String str = ReflectionGetCard.getSubscriberId(context,tm,ReflectionGetCard.getDefaultDataSubId(context));
否則 華為榮亞8 會卡死,不知道什么願意?有知道的小伙伴或者大神給解答下!謝謝!歡迎隨時交流:847638676(同微信)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM