2012-05-10 128 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 –