关于监听SIM卡状态变化广播判断SIM卡当前状态的方法

关于监听SIM卡状态变化广播判断SIM卡当前状态的方法

一、问题:

终端启动后,APP层检测SIM卡的注册状态,连续收到4个ACTION_SIM_STATE_CHANGED广播,获取其系统的SIM state 状态时发现都是处于 TelephonyManager.SIM_STATE_READY 状态,如图:
关于监听SIM卡状态变化广播判断SIM卡当前状态的方法
需要找到为何在 TelephonyManager.SIM_STATE_READY 之后连续发送4次ACTION_SIM_STATE_CHANGED广播,SIM卡状态监听代码如图:
关于监听SIM卡状态变化广播判断SIM卡当前状态的方法

二、代码跟踪:

跟踪Logcat发现开机时可以监听到如下4次ACTION_SIM_STATE_CHANGED广播,如下图:
关于监听SIM卡状态变化广播判断SIM卡当前状态的方法
系统确实发出了4次ACTION_SIM_STATE_CHANGED广播,但是SIM卡状态的变化如下:
NOT_READY --> READY --> IMSI --> LOAD
并且从Logcat日志打印的时间,跟客户给出的时间间隔相比较,比较吻合。找到该日志打印的地方( SimStateReceiver.java 源码文件中),添加日志以作判断

// An highlighted block
@Override 
public void onReceive(Context context, Intent intent) {
    final String action = intent.getAction();
    mContext = context;
    if (DBG)
        log("received broadcast " + action);
    if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
        final int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY,
                SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId()));
        final String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
        final int simState;
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);     //_lcg_++ 添加用于打印SIM状态日志的代码
        int state = tm.getSimState();     //_lcg_++ 添加用于打印SIM状态日志的代码
        if (DBG)
            log("ACTION_SIM_STATE_CHANGED intent received on sub = " + slotId
                    + " SIM STATE IS " + stateExtra + ", state = " + state);    //_lcg_++ 添加用于打印SIM状态日志的代码

        if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
                || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)
                || IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
            simState = SimContactsConstants.SIM_STATE_READY;
        }
        else if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)
                || IccCardConstants.INTENT_VALUE_ICC_UNKNOWN.equals(stateExtra)
                || IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
            simState = SimContactsConstants.SIM_STATE_ERROR;
        } else {
            simState = SimContactsConstants.SIM_STATE_NOT_READY;
        }
        log("ACTION_SIM_STATE_CHANGED intent on slotId = " + slotId + " simState = " + simState);
        sendSimState(slotId, simState);

跟踪日志发现,此处所获取的SIM的状态均为state = 5也即state = TelephonyManager.SIM_STATE_READY,说明使用这个状态作为判断的依据有所不妥。

三、问题解决:

修改SIM卡是否初始化就绪的判断,更正为接收到系统ACTION_SIM_STATE_CHANGED广播的时后,获取该广播所携带的参数 IccCardConstants.INTENT_KEY_ICC_STATE的值作为判断依据,并根据获取的状态参数,判断此时广播参数值为 IccCardConstants.INTENT_VALUE_ICC_LOADED才会判断为SIM卡完全初始化完成,状态就绪。