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
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.
}
}
}
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:
If I then take it out of flight mode, the following Intents are broadcast:
It is possible that different manufacturers and different models behave differently. As they say, "Your mileage may vary".
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
.