如何监控SIM状态变化

Gia*_*nzi 25 android broadcastreceiver android-service telephonymanager

我希望能够在SIM状态改变时做一些事情,即在需要SIM PIN时播放声音,但我认为没有广播事件可以被广播接收器截获...注册android.intent.action .PHONE_STATE只会告诉你CALL-STATE何时发生变化.另一种方法是启动一个注册PhoneStateListener的服务并对LISTEN_SERVICE_STATE作出反应(当状态为OUT-OF-STATE时它可以获取SIM从TelephonyManager状态并查看状态是否为SIM_STATE_PIN_REQUIRED).所以,我的问题是:

1)是否有任何广播意图可用于拦截SIM状态变更或服务状态变更?

2)ServiceStateListener接收到电话状态改变的通知后,在服务中安装PhoneStateListener并使用它向服务本身传递意图是一个坏主意吗?

Dav*_*ser 28

android.intent.action.SIM_STATE_CHANGED当SIM状态改变时,广播Intent .例如,在我的带有T-Mobile SIM卡的HTC Desire上,如果我将设备置于飞行模式,则广播以下意图:

  • Intent:android.intent.action.SIM_STATE_CHANGED with extras:ss = NOT_READY,reason = null

如果我将其从飞行模式中取出,则会广播以下意图:

  • 意图:android.intent.action.SIM_STATE_CHANGED附加:ss = LOCKED,reason = PIN
  • Intent:android.intent.action.SIM_STATE_CHANGED with extras:ss = READY,reason = null
  • 意图:android.intent.action.SIM_STATE_CHANGED with extras:ss = IMSI,reason = null
  • Intent:android.intent.action.SIM_STATE_CHANGED with extras:ss = LOADED,reason = null

不同的制造商和不同的模型可能表现不同.正如他们所说,"你的里程可能会有所不同".

  • 我不知道是否或在何处记录.我通过观察logcat来查看当某些电话事件发生时广播的Intent,然后编写监听这些事件并转储其内容的小型测试程序,从而凭经验发现了这一点.由于其中很多是特定于供应商的,因此您必须自己解决这个问题.很高兴我能得到一些帮助. (6认同)
  • 在文档中没有提到android源代码具有TelephonyIntents类的这些意图,并且警告永远不要听它们https://android.googlesource.com/platform/frameworks/base/+/cd92588/telephony/java/ COM /安卓/内部/电话/ TelephonyIntents.java (3认同)

Tim*_*Tim 5

大卫的回答是正确的。我想添加一些示例代码来帮助人们开始实现这样的状态监视器。

/**
 * 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.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)