web-dev-qa-db-ja.com

SIMの状態変化を監視する方法

SIMの状態が変化したときに何かできるようにしたいのです。つまり、SIM PINが必要なときに音を鳴らしますが、インターセプトできるブロードキャストイベントはないと思います。このためのブロードキャストレシーバー...Android.intent.action。PHONE_STATEの登録は、CALL-STATEが変更されたときにのみ通知します。 PhoneStateListenerを登録し、LISTEN_SERVICE_STATEに反応するサービスを開始します(状態がOUT-OF-STATEの場合、TelephonyManagerそして状態がSIM_STATE_PIN_REQUIREDであるかどうかを確認します。したがって、私の質問は次のとおりです。

1) SIM状態の変更またはサービス状態の変更をインターセプトするために使用できるブロードキャストインテントはありますか?

2)サービス内にPhoneStateListenerをインストールし、それを使用してサービス自体にインテントを配信することは悪い考えですPhoneStateListenerが受け取った電話状態変更の通知?

25
Gianni Costanzi

インテントAndroid.intent.action.SIM_STATE_CHANGEDは、SIMの状態が変化したときにブロードキャストされます。たとえば、T-Mobile SIMカードを使用したHTC Desireでデバイスをフライトモードにすると、次のインテントがブロードキャストされます。

  • インテント:Android.intent.action.SIM_STATE_CHANGED with extras:ss = NOT_READY、reason = null

その後、フライトモードを解除すると、次のインテントがブロードキャストされます。

  • インテント:Android.intent.action.SIM_STATE_CHANGED with extras:ss = LOCKED、reason = PIN
  • インテント:Android.intent.action.SIM_STATE_CHANGED with extras:ss = READY、reason = null
  • インテント:Android.intent.action.SIM_STATE_CHANGED with extras:ss = IMSI、reason = null
  • インテント:Android.intent.action.SIM_STATE_CHANGED with extras:ss = LOADED、reason = null

メーカーやモデルによって動作が異なる可能性があります。彼らが言うように、「あなたの走行距離は変わるかもしれません」。

28
David Wasser

デビッドの答えはその場にあります。私は人々がそのような状態モニターの実装を始めるのを助けるためにいくつかのサンプルコードを追加したかったのです。

/**
 * 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.
        }
    }
}
4
Tim

onServiceStateChanged() をリッスンするサービスで PhoneStateListener を使用する2番目のアプローチは私にとってはうまくいきました。一部のデバイスでは内部ブロードキャストを受信できないと思いますAndroid.intent.action.SIM_STATE_CHANGED

1
VladimirVip