双卡双待获取正在联网的运营商的IMSI

**

文章已过时,通过现有代码可判断

**
背景:
以前google默认的是单卡的,
双卡双待为国内厂商定制,
所以没有直接的系统API来获取正在联网的是哪张卡;
步骤:
主要分三种情况:
1、Android5.0之前的,目前先放弃
2、在Android5.0后可以通过ISub来获取哪张卡在联网,
通过反射获取对应的IMSI
3、Android7.0后通过SubscriptionManager.getDefaultDataSubscriptionId();获取联网卡槽的信息,再根据反射获取对应的IMSI
主要代码如下:

package com.main.common.utils;

import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;


import com.android.internal.telephony.ISub;
import com.ylmf.androidclient.DiskApplication;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author zhanshuyong
 * @date 2018/5/23
 * Description:
 * 不管是否为双卡双待,可以获取正在联网的那张卡的IMSI
 * https://blog.csdn.net/ymcl_hx/article/details/53484797
 * https://blog.csdn.net/linsir007/article/details/51918227
 * https://blog.csdn.net/u013686019/article/details/71195230
 * https://blog.csdn.net/u012904691/article/details/78032076
 * }
 */
public class TelephonyManagerUtil {

    /**
     * 获取正在联网的那张手机卡  的 imsi值
     *
     * @return
     */
    public static String getIMSI() {
        String IMSI = "";

        int dataSubId = 0;
        try {

            Method method;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                dataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
            } else {
                ISub iSub = getISub();
                if (iSub != null) {
                    dataSubId = getISub().getDefaultDataSubId();
                }
            }
            TelephonyManager telephonyManager = (TelephonyManager) DiskApplication.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> telephonyClass = telephonyManager.getClass();
            //如果是5.0的反射long型
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
                method = telephonyClass.getMethod("getSubscriberId", long.class);
            } else {
                //5.0以后用int
                method = telephonyClass.getMethod("getSubscriberId", int.class);
            }
            IMSI = method.invoke(telephonyManager, dataSubId).toString();
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | RemoteException e) {
            e.printStackTrace();
        }
        Logger.azhansy("getSubId= " + dataSubId + "  IMSI=" + IMSI);

        return IMSI;
    }

    /**
     * 5.0以后 android就加了这个
     *
     * @return
     */
    private static ISub getISub() {

        try {
            return ISub.Stub.asInterface((IBinder) Class.forName("android.os.ServiceManager").getMethod("getService", String.class).invoke(null, "isub"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

Android5.0后通过iSub.aidl:
注意包名、反射的使用:
这里写图片描述

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * https://github.com/aosp-mirror/platform_frameworks_base/blob/4b1a8f46d6ec55796bf77fd8921a5a242a219278/telephony/java/com/android/internal/telephony/ISubscriptionListener.aidl
 */

package com.android.internal.telephony;

import android.app.PendingIntent;
import android.telephony.SubscriptionInfo;
import com.android.internal.telephony.ISubscriptionListener;

interface ISub {
    /**
     * @param callingPackage The package maing the call.
     * @return a list of all subscriptions in the database, this includes
     * all subscriptions that have been seen.
     */
    List<SubscriptionInfo> getAllSubInfoList(String callingPackage);

    /**
     * @param callingPackage The package maing the call.
     * @return the count of all subscriptions in the database, this includes
     * all subscriptions that have been seen.
     */
    int getAllSubInfoCount(String callingPackage);

    /**
     * Get the active SubscriptionInfo with the subId key
     * @param subId The unique SubscriptionInfo key in database
     * @param callingPackage The package maing the call.
     * @return SubscriptionInfo, maybe null if its not active
     */
    SubscriptionInfo getActiveSubscriptionInfo(int subId, String callingPackage);

    /**
     * Get the active SubscriptionInfo associated with the iccId
     * @param iccId the IccId of SIM card
     * @param callingPackage The package maing the call.
     * @return SubscriptionInfo, maybe null if its not active
     */
    SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage);

    /**
     * Get the active SubscriptionInfo associated with the slotIdx
     * @param slotIdx the slot which the subscription is inserted
     * @param callingPackage The package maing the call.
     * @return SubscriptionInfo, maybe null if its not active
     */
    SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx, String callingPackage);

    /**
     * Get the SubscriptionInfo(s) of the active subscriptions. The records will be sorted
     * by {@link SubscriptionInfo#getSimSlotIndex} then by {@link SubscriptionInfo#getSubscriptionId}.
     *
     * @param callingPackage The package maing the call.
     * @return Sorted list of the currently {@link SubscriptionInfo} records available on the device.
     * <ul>
     * <li>
     * If null is returned the current state is unknown but if a {@link OnSubscriptionsChangedListener}
     * has been registered {@link OnSubscriptionsChangedListener#onSubscriptionsChanged} will be
     * invoked in the future.
     * </li>
     * <li>
     * If the list is empty then there are no {@link SubscriptionInfo} records currently available.
     * </li>
     * <li>
     * if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
     * then by {@link SubscriptionInfo#getSubscriptionId}.
     * </li>
     * </ul>
     */
    List<SubscriptionInfo> getActiveSubscriptionInfoList(String callingPackage);

    /**
     * @param callingPackage The package making the call.
     * @return the number of active subscriptions
     */
    int getActiveSubInfoCount(String callingPackage);

    /**
     * @return the maximum number of subscriptions this device will support at any one time.
     */
    int getActiveSubInfoCountMax();

    /**
     * Add a new SubscriptionInfo to subinfo database if needed
     * @param iccId the IccId of the SIM card
     * @param slotId the slot which the SIM is inserted
     * @return the URL of the newly created row or the updated row
     */
    int addSubInfoRecord(String iccId, int slotId);

    /**
     * Set SIM icon tint color by simInfo index
     * @param tint the icon tint color of the SIM
     * @param subId the unique SubscriptionInfo index in database
     * @return the number of records updated
     */
    int setIconTint(int tint, int subId);

    /**
     * Set display name by simInfo index
     * @param displayName the display name of SIM card
     * @param subId the unique SubscriptionInfo index in database
     * @return the number of records updated
     */
    int setDisplayName(String displayName, int subId);

    /**
     * Set Sim Provisioning Status by subscription ID
     * @param simProvisionStatus with the subscription:
     * {@See SubscriptionManager#SIM_PROVISIONED}
     * {@See SubscriptionManager#SIM_UNPROVISIONED_COLD}
     * {@See SubscriptionManager#SIM_UNPROVISIONED_OUT_OF_CREDIT}
     * @param subId the unique SubInfoRecord index in database
     * @return the number of records updated
     */
    int setSimProvisioningStatus(int simProvisioningStatus, int subId);

    /**
     * Set display name by simInfo index with name source
     * @param displayName the display name of SIM card
     * @param subId the unique SubscriptionInfo index in database
     * @param nameSource, 0: DEFAULT_SOURCE, 1: SIM_SOURCE, 2: USER_INPUT
     * @return the number of records updated
     */
    int setDisplayNameUsingSrc(String displayName, int subId, long nameSource);

    /**
     * Set phone number by subId
     * @param number the phone number of the SIM
     * @param subId the unique SubscriptionInfo index in database
     * @return the number of records updated
     */
    int setDisplayNumber(String number, int subId);

    /**
     * Set data roaming by simInfo index
     * @param roaming 0:Don't allow data when roaming, 1:Allow data when roaming
     * @param subId the unique SubscriptionInfo index in database
     * @return the number of records updated
     */
    int setDataRoaming(int roaming, int subId);

    int getSlotId(int subId);

    int[] getSubId(int slotId);

    int getDefaultSubId();

    int clearSubInfo();

    int getPhoneId(int subId);

    /**
     * Get the default data subscription
     * @return Id of the data subscription
     */
    int getDefaultDataSubId();

    void setDefaultDataSubId(int subId);

    int getDefaultVoiceSubId();

    void setDefaultVoiceSubId(int subId);

    int getDefaultSmsSubId();

    void setDefaultSmsSubId(int subId);

    void clearDefaultsForInactiveSubIds();

    int[] getActiveSubIdList();

    void setSubscriptionProperty(int subId, String propKey, String propValue);

    String getSubscriptionProperty(int subId, String propKey, String callingPackage);

    /**
     * Get the SIM state for the slot idx
     * @return SIM state as the ordinal of IccCardConstants.State
     */
    int getSimStateForSlotIdx(int slotIdx);

    boolean isActiveSubId(int subId);
}
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import android.telephony.SubscriptionInfo;

oneway interface ISubscriptionListener {
    void onSubscriptionInfoChanged();
}

参考:
https://blog.csdn.net/ymcl_hx/article/details/53484797
https://blog.csdn.net/linsir007/article/details/51918227
https://blog.csdn.net/u013686019/article/details/71195230
https://blog.csdn.net/u012904691/article/details/78032076

猜你喜欢

转载自blog.csdn.net/azhansy/article/details/80424282