2012-05-10 142 views
24

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

1)是否有任何广播意图,我可以用来拦截SIM状态更改或服务状态更改?

2)是一个坏主意,安装服务中的PhoneStateListener,并用它在手机状态的通知,交付意图服务本身改由PhoneStateListener收到?

回答

23

在SIM状态改变时广播意图android.intent.action.SIM_STATE_CHANGED。例如,在我与T-Mobile的SIM卡的HTC Desire,如果我把设备进入飞行模式下意图是广播:

  • 意图:与演员android.intent.action.SIM_STATE_CHANGED:SS = NOT_READY ,原因= NULL

如果我再取出来的飞行模式,下面的意图是广播:

  • 意图:android.intent.action.SIM_STATE_CHANGED与演员:SS =锁定,原因= PIN
  • 意图:与额外android.intent.action.SIM_STATE_CHANGED:SS = READY,原因= NULL
  • 意图:与额外android.intent.action.SIM_STATE_CHANGED:SS = IMSI,原因= NULL
  • 意图:android.intent .action.SIM_STATE_CHANGED with extras:ss = LOADED,reason = null

不同制造商和不同型号的行为可能有所不同。正如他们所说,“你的里程可能会有所不同”。

+0

非常感谢!我应该在Android Reference Docs中找到这些信息?这种意图在哪个阶段被记录? –

+4

我不知道是否或在哪里这是记录。我已经通过观察logcat发现了这一点,以了解某些电话事件发生时什么是Intents,然后编写小型测试程序来监听这些事件并转储它们的内容。由于很多这是供应商特定的,你几乎必须为自己弄明白。很高兴我可以得到一些帮助。 –

+0

我已经在我的HTC One X上进行了测试,它的工作原理,非常感谢!我不明白为什么有些东西在官方SDK参考文档中记录得很差(或者可能存在文档,但很难找到) –

1

在服务中侦听onServiceStateChanged()PhoneStateListener为我工作的第二种方法。我相信在某些设备上,您将无法获得内部广播android.intent.action.SIM_STATE_CHANGED

+0

“我相信在某些设备上你不会得到内部广播” - 我认为你遇到了一个安全功能,如果该应用还没有被用户启动或强制停止 – for3st

2

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

/** 
* 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

就像魅力一样工作将不会播出广播! +1 –