Method of Judging Current Status of SIM Card by Listening for SIM Card State Change Broadcast

Keywords: Java

Method of Judging Current Status of SIM Card by Listening for SIM Card State Change Broadcast

1. Questions:

After the terminal starts, the APP layer detects the registration status of the SIM card, and receives four successive ACTION_SIM_STATE_CHANGED broadcasts. When getting the SIM state of its system, it finds that they are all in the TelephonyManager.SIM_STATE_READY state, as shown in the following figure:

You need to find out why ACTION_SIM_STATE_CHANGED broadcasts are sent four times in a row after TelephonyManager.SIM_STATE_READY, and the SIM card status monitoring code is shown in the following figure:

2. Code tracking:

The following four ACTION_SIM_STATE_CHANGED broadcasts can be listened to when the tracking Logcat finds that it is on, as shown below:

The system did issue four broadcasts of ACTION_SIM_STATE_CHANGED, but the status of the SIM card changed as follows:
NOT_READY --> READY --> IMSI --> LOAD
And the time printed from the Logcat log matches the time interval given by the customer.Find where the log is printed (in the SimStateReceiver.java source file) and add the log for judgment

// 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_++ Add code to print SIM status logs
        int state = tm.getSimState();     //_lcg_++ Add code to print SIM status logs
        if (DBG)
            log("ACTION_SIM_STATE_CHANGED intent received on sub = " + slotId
                    + " SIM STATE IS " + stateExtra + ", state = " + state);    //_lcg_++ Add code to print SIM status logs

        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);

The trace log found that the SIM status obtained here is state = 5, that is, state = TelephonyManager.SIM_STATE_READY, indicating that it is inappropriate to use this status as a basis for judgment.

3. Problem solving:

Modify the judgment of whether the SIM card is ready for initialization. Correct it to get the value of the parameter IccCardConstants.INTENT_KEY_ICC_STATE carried by the broadcast when the system ACTION_SIM_STATE_CHANGED broadcast is received as the judgment basis. Based on the obtained status parameters, the value of the broadcast parameter IccCardConstants.INTENT_VALUE_ICC_LOADED will judge that the SIM card is fully initialized.Complete, ready to go.

Posted by Garrett on Tue, 30 Apr 2019 07:50:37 -0700