Как контролировать изменение состояния SIM-карты
Я хотел бы иметь возможность делать некоторые вещи, когда состояние SIM-карты меняется, т.е. воспроизводить звук, когда требуется PIN-код SIM-карты, но я думаю, что нет вещательных событий, которые могут быть перехвачены вещательным приемником для этого. Регистрация для android.intent.action.PHONE_STATE сообщает только, когда изменяется CALL-STATE. Альтернативой может быть запуск службы, которая регистрирует PhoneStateListener и реагирует на LISTEN_SERVICE_STATE (когда состояние OUT-OF-STATE оно может получить состояние SIM из TelephonyManager и посмотреть, является ли состояние SIM_STATE_PIN_REQUIRED). Итак, мои вопросы:
1) Есть ли какое-либо намерение трансляции, которое я могу использовать для перехвата изменения состояния SIM-карты или изменения состояния службы?
2) - это плохая идея установить PhoneStateListener в пределах Сервиса и использовать его для доставки намерений самой службе после уведомления о состоянии телефона, измененного, полученном PhoneStateListener?
Ответы
Ответ 1
Intent android.intent.action.SIM_STATE_CHANGED
передается при изменении состояния SIM-карты. Например, на моем HTC Desire с SIM-картой T-Mobile, если я поставлю устройство в режим полета, будет транслироваться следующий Intent:
- Назначение: android.intent.action.SIM_STATE_CHANGED с дополнительными функциями: ss = NOT_READY, reason = null
Если я вывешу его из режима полета, транслируются следующие намерения:
- Цель: android.intent.action.SIM_STATE_CHANGED с дополнительными функциями: ss = LOCKED, reason = PIN
- Назначение: android.intent.action.SIM_STATE_CHANGED с дополнительными функциями: ss = READY, reason = null
- Назначение: android.intent.action.SIM_STATE_CHANGED с дополнительными функциями: ss = IMSI, reason = null
- Назначение: android.intent.action.SIM_STATE_CHANGED с дополнительными функциями: ss = LOADED, reason = null
Возможно, что разные производители и разные модели ведут себя по-разному. Как говорится, "Ваш пробег может отличаться".
Ответ 2
Второй подход: PhoneStateListener в Службе, которая слушает onServiceStateChanged() работал у меня. Я считаю, что на некоторых устройствах вы не получите внутреннюю трансляцию android.intent.action.SIM_STATE_CHANGED
.
Ответ 3
Ответ Дэвида на место. Я хотел добавить примерный код, чтобы помочь людям начать работу с таким монитором состояния.
/**
* 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.
}
}
}