How to monitor SIM state change

后端 未结 3 1854
孤独总比滥情好
孤独总比滥情好 2020-11-27 14:15

I\'d like to be able to do some stuff when the SIM state change, i.e. play a sound when SIM PIN is required, but I think there are no Broadcast events that can be intercepte

相关标签:
3条回答
  • 2020-11-27 14:27

    David's answer is spot on. I wanted to add some example code to help people get started with implementing such a state monitor.

    /**
     * Handles broadcasts related to SIM card state changes.
     * <p>
     * Possible states that are received here are:
     * <p>
     * Documented:
     * ABSENT
     * NETWORK_LOCKED
     * PIN_REQUIRED
     * PUK_REQUIRED
     * READY
     * UNKNOWN
     * <p>
     * Undocumented:
     * NOT_READY (ICC interface is not ready, e.g. radio is off or powering on)
     * CARD_IO_ERROR (three consecutive times there was a SIM IO error)
     * IMSI (ICC IMSI is ready in property)
     * LOADED (all ICC records, including IMSI, are loaded)
     * <p>
     * Note: some of these are not documented in
     * https://developer.android.com/reference/android/telephony/TelephonyManager.html
     * but they can be found deeper in the source code, namely in com.android.internal.telephony.IccCardConstants.
     */
    public class SimStateChangedReceiver extends BroadcastReceiver {
    
        /**
         * This refers to com.android.internal.telehpony.IccCardConstants.INTENT_KEY_ICC_STATE.
         * It seems not possible to refer it through a builtin class like TelephonyManager, so we
         * define it here manually.
         */
        private static final String EXTRA_SIM_STATE = "ss";
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            String state = intent.getExtras().getString(EXTRA_SIM_STATE);
            if (state == null) {
                return;
            }
    
            // Do stuff depending on state   
            switch (state) {      
                case "ABSENT": break;
                case "NETWORK_LOCKED": break;
                // etc.
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 14:37

    The Intent android.intent.action.SIM_STATE_CHANGED is broadcast when the SIM state changes. For example, on my HTC Desire with a T-Mobile SIM card, if I put the device into flight mode the following Intent is broadcast:

    • Intent: android.intent.action.SIM_STATE_CHANGED with extras: ss = NOT_READY, reason = null

    If I then take it out of flight mode, the following Intents are broadcast:

    • Intent: android.intent.action.SIM_STATE_CHANGED with extras: ss = LOCKED, reason = PIN
    • Intent: android.intent.action.SIM_STATE_CHANGED with extras: ss = READY, reason = null
    • Intent: android.intent.action.SIM_STATE_CHANGED with extras: ss = IMSI, reason = null
    • Intent: android.intent.action.SIM_STATE_CHANGED with extras: ss = LOADED, reason = null

    It is possible that different manufacturers and different models behave differently. As they say, "Your mileage may vary".

    0 讨论(0)
  • 2020-11-27 14:37

    The second approach of having a PhoneStateListener in a Service that listens for onServiceStateChanged() worked for me. I believe that on some devices you will not get the internal broadcast android.intent.action.SIM_STATE_CHANGED.

    0 讨论(0)
提交回复
热议问题