24

Me gustaría poder hacer algunas cosas cuando el estado de la tarjeta SIM cambia, es decir, reproducir un sonido cuando se requiere PIN de SIM, pero creo que no hay eventos de difusión que puedan ser interceptados por un receptor de difusión para esto ... registrándose para android.intent.action .PHONE_STATE solo indica cuándo cambia el CALL-STATE. Una alternativa puede ser iniciar un servicio que registra PhoneStateListener y reacciona ante LISTEN_SERVICE_STATE (cuando el estado está FUERA DE ESTADO, puede obtener el estado SIM del TelephonyManager y observar si el estado es SIM_STATE_PIN_REQUIRED). Entonces, mis preguntas son:Cómo supervisar el cambio de estado SIM

1) ¿Hay 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 utilizarlo para entregar las intenciones al propio servicio de la notificación de un estado del teléfono cambiado recibida por el PhoneStateListener?

Respuesta

23

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

  • Intención: android.intent.action.SIM_STATE_CHANGED con extras: ss = NOT_READY , razón = null

Si entonces me lo saco del modo de vuelo, los siguientes Intentos se emiten:

  • Intención: android.intent.action.SIM_STATE_CHANGED con extras: ss = BLOQUEADO, razón = PIN
  • Intención: android.intent.action.SIM_STATE_CHANGED con extras: ss = LISTO, razón = null
  • Intención: android.intent.action.SIM_STATE_CHANGED con extras: ss = IMSI, razón = null
  • Intención: android.intent .action.SIM_STATE_CHANGED con extras: ss = LOADED, reason = null

Es posible que diferentes fabricantes y modelos diferentes tengan un comportamiento diferente. Como dicen, "su kilometraje puede variar".

+0

¡Muchas gracias! ¿Dónde debería haber encontrado esta información dentro de los Documentos de Referencia de Android? ¿Bajo qué clase está documentada esta intención? –

+4

No tengo idea si o dónde está documentado esto. Lo he descubierto empíricamente observando el logcat para ver qué Intents se transmiten cuando ocurren ciertos eventos de telefonía y luego escribo pequeños programas de prueba que escuchan estos eventos y vuelcan sus contenidos. Como mucho de esto es específico del vendedor, tienes que resolverlo por ti mismo. Me alegro de poder ser de alguna ayuda. –

+0

He probado en mi HTC One X y funciona, ¡muchas gracias! No entiendo por qué algunas cosas están tan mal documentadas en la referencia oficial de SDK (o tal vez la documentación existe, pero es difícil encontrarla) –

1

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.

+0

"Creo que en algunos dispositivos no obtendrás broadcas internas" - Creo que encuentras una característica de seguridad donde la transmisión no se entregará si la aplicación aún no ha sido iniciada por el usuario o si la fuerza se detuvo – for3st

2

La respuesta de David es perfecta. 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. 
* <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

¡funciona como el encanto! +1 –

Cuestiones relacionadas