Cómo monitorear el cambio de estado de SIM

Me gustaría poder hacer algunas cosas cuando el estado de la SIM cambie, es decir, reproducir un sonido cuando se requiera el PIN de la SIM, pero creo que no hay eventos de Transmisión que puedan ser interceptados por un receptor de transmisión para esto … registrarse para android.intent.action .PHONE_STATE solo indica cuándo cambia CALL-STATE. Una alternativa puede ser iniciar un servicio que registre un PhoneStateListener y reaccione ante LISTEN_SERVICE_STATE (cuando el estado es FUERA DE ESTADO puede recibir el SIM estado de TelephonyManager y observe si el estado es SIM_STATE_PIN_REQUIRED). Entonces, mis preguntas son:

1) ¿Existe alguna intención de transmisión que pueda usar para interceptar un cambio de estado SIM o un cambio de estado de servicio?

2) ¿ es una mala idea instalar un PhoneStateListener dentro de un Servicio y usarlo para entregar los bashs al Servicio mismo al recibir la notificación de un cambio de estado del teléfono recibido por PhoneStateListener ?

El bash android.intent.action.SIM_STATE_CHANGED se transmite cuando cambia el estado de la SIM. Por ejemplo, en mi HTC Desire con una tarjeta SIM de T-Mobile, si pongo el dispositivo en modo de vuelo, se emite el siguiente Intención:

  • Propósito: android.intent.action.SIM_STATE_CHANGED con extras: ss = NOT_READY, reason = null

Si lo saco del modo de vuelo, se transmiten los siguientes Intents:

  • Propósito: android.intent.action.SIM_STATE_CHANGED con extras: ss = LOCKED, reason = PIN
  • Propósito: android.intent.action.SIM_STATE_CHANGED con extras: ss = READY, reason = null
  • Propósito: android.intent.action.SIM_STATE_CHANGED con extras: ss = IMSI, reason = null
  • Propósito: android.intent.action.SIM_STATE_CHANGED con extras: ss = LOADED, reason = null

Es posible que diferentes fabricantes y diferentes modelos se comporten de manera diferente. Como dicen, “su kilometraje puede variar”.

La respuesta de David es acertada. Quería agregar un código de ejemplo para ayudar a las personas a comenzar a implementar dicho monitor de estado.

 /** * Handles broadcasts related to SIM card state changes. * 

* Possible states that are received here are: *

* Documented: * ABSENT * NETWORK_LOCKED * PIN_REQUIRED * PUK_REQUIRED * READY * UNKNOWN *

* Undocumented: * NOT_READY (ICC interface is not ready, eg 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) *

* 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. } } }

El segundo enfoque de tener un PhoneStateListener en un servicio que escucha onServiceStateChanged () funcionó para mí. Creo que en algunos dispositivos no obtendrás la transmisión interna android.intent.action.SIM_STATE_CHANGED .