天天看點

随意切換雙卡流量,立即擷取對應卡的SMIS - 蝸牛起飛吧

随意切換雙卡流量,立即擷取對應卡的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(同微信)