2011-02-18 78 views
10

我試圖使用BroadcastReceiver來檢測手機從WiFi接入點斷開連接。要做到這一點,我登記我的清單中的廣播接收器:檢測從WiFi接入點斷開連接

<receiver android:name="com.eshayne.android.WiFiBroadcastReceiver"> 
    <intent-filter> 
     <action android:name="android.net.wifi.STATE_CHANGE" /> 
    </intent-filter> 
</receiver> 

在我WiFiBroadcastReceiver類,我檢查了NETWORK_STATE_CHANGED_ACTION動作和看的NetworkInfo的詳細狀態:

if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 
    NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 
    android.util.Log.d("com.eshayne.android.WiFiBroadcastReceiver", "network state change - detailedState=" + info.getDetailedState() + ": " + info.toString()); 
    if (info.getDetailedState() == DetailedState.DISCONNECTED) { 
     ... 
    } 
    else if (info.getDetailedState() == DetailedState.CONNECTED) { 
     ... 
    } 

我的問題米看到的是,當手機離開WiFi接入點的範圍,我的「斷開」回調被稱爲6次 - 相當有規律地大約每隔15秒 - 在它停止之前。到目前爲止,我還沒有能夠找到每個回調的NetworkInfo之間的任何區別特徵。被寫入日誌中的每個NetworkInfo對象是這樣的:

02-18 10:16:51.918 D/com.eshayne.android.WiFiBroadcastReceiver(1511): network state change - detailedState=DISCONNECTED: NetworkInfo: type: WIFI[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true 

它也沒有電話徘徊在進出無線網絡範圍內的問題,因爲我的「連接」回調不是「斷開連接」回調之間稱爲。兩者之間也沒有其他國家被觸發。只是一個快速的6個回調系列,每個回調都有一個詳細的DISCONNECTED狀態。

有沒有更好的方式讓我檢測手機何時失去了WiFi連接,以便我的回調只在每次斷開連接時被調用一次?或者通過任何方式來檢測我看到的6個回調中的哪一個是「最終」回調?

+0

問題到底是什麼?當你說手機在第一次廣播後沒有重新連接時,是不是與其他6一樣好? – 2011-02-18 17:04:13

+0

問題是我不希望我的廣播接收器執行六次相同的斷開連接處理邏輯。 – eshayne 2011-02-18 17:43:04

回答

2

你說這是一個「6個不連續回調的快速系列」,但是你的if/else-如果只檢查DISCONNECTED和CONNECTED,看起來沒有默認塊來處理所有其他情況。從NetworkInfo.DetailedState api頁面,NetworkInfo.getDetailedState()可能會返回10個可能的狀態,包括「連接」,「掃描」,「斷開連接」,所有這些對於剛斷開連接的電話都是合理的行爲網絡。

拋出一個默認情況下,提醒您任何更改在WiFi狀態,不只是「連接」和「斷開」。你可能會發現手機正在幾個不同的狀態之間轉動,而不只是六次向你射出同一個手機。希望從那裏,如何在你的代碼中進行將會更清楚一點。

0

您可以使用的一種解決方法是保持最後一次回調操作(全局狀態,共享首選項等),並且只在操作發生變化時才運行回調。

enum NetworkCallbackAction { None, Disconnected, Connected }; 
NetworkCallbackAction lastHandledAction = NetworkCallbackAction.None; 

// ... 

if (info.getDetailedState() == DetailedState.DISCONNECTED) { 
    if (lastHandledAction != NetworkCallbackAction.Disconnected) { 
    lastHandledAction = NetworkCallbackAction.Disconnected; 
    // ... 
    } 
} 
else if (info.getDetailedState() == DetailedState.CONNECTED) { 
    if (lastHandledAction != NetworkCallbackAction.Connected) { 
    lastHandledAction = NetworkCallbackAction.Connected; 
    // ... 
    } 
} 

這種邏輯的一個更好的抽象是寫廣播接收機誰的唯一工作就是規範網絡狀態變爲一致的事件,並順利出真實世界的怪癖,然後重新播放自己的行動。這使您可以將原始更新簡化爲對您的應用程序有意義的內容。例如,它可以記住它是最後一次廣播,只是廣播更改(類似於上面的代碼)。在發生網絡改變意圖爆發的情況下,它可能會等待幾秒鐘,然後廣播最後收到的狀態。