2011-02-18 14 views
10

ブロードキャストレシーバを使用して、電話機がWiFiアクセスポイントから切断されたことを検出しようとしています。これを行うには、私はマニフェストで私BroadcastReceiverを登録: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秒に1回、かなり定期的に停止してから停止します。これまでのところ、私は各コ​​ールバックの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 

私の「接続」コールバックは「切断」のコールバックの間に呼び出されないように、それは、また、無線LANの範囲の内外放浪電話の問題ではありません。それらの間に他の状態が引き起こされることもありません。詳細状態がDISCONNECTEDである6コールバックのちょうど速いシリーズ。

私のコールバックが切断ごとに1回だけ呼び出されるように、電話機がWiFi接続を失ったときを検出する良い方法はありますか?または、私が見ている6つのコールバックのどれが「最終的な」ものかを検出する方法はありますか?

+0

ここで問題は何ですか?あなたは、電話が最初の放送の後に再接続していないと言うとき、6のどれも他のものと比べて良いものではないのですか? –

+0

問題は、ブロードキャストレシーバーで同じ切断処理ロジックを6回実行したくないということです。 – eshayne

答えて

2

あなたは「6つの切断されたコールバックの急速なシリーズ」だと言いますが、if/else-ifはDISCONNECTEDとCONNECTEDをチェックし、他のすべてのケースを処理するデフォルトブロックのようには見えません。 NetworkInfo.DetailedState apiページには、「接続」、「スキャン」、「切断」など、NetworkInfo.getDetailedState()によって返される可能性のある10の状態があります。これらの状態はすべて、接続が切断されたばかりのネットワーク。

「CONNECTED」と「DISCONNECTED」だけでなく、に「」の変更を通知するデフォルトのケースをスローダウンします。あなたは、電話がいくつかの異なる州の間で回転していることに気がつくかもしれません。ちょうど同じものを6回あなたに撃ち殺すだけではありません。うまくいけば、あなたのコードを進める方法が少しはっきりします。

+0

ありがとうございます。私は明らかにしておくべきです - 私は実際に接続されているか切断されているかを確認する前に、NetworkInfo全体をログに記録しています。彼らはすべて切断されています。元の投稿を更新して、すべてのログエントリの外観を表示しました。それぞれのコールバックを区別するために何か他のものを考えることができると思うなら、それを試してみましょう。 – eshayne

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; 
    // ... 
    } 
} 

一貫性のイベントにネットワーク状態の変化を正規化し、実世界の癖を滑らかにし、その後、再放送、自身の行動することです。これにより、生の更新をアプリケーションに合ったものに簡単にすることができます。たとえば、最後のブロードキャストであり、ブロードキャストの変更のみを思い出すことができます(上記のコードと同様)。ネットワーク変更インテントのバーストの場合、受信した最後の状態をブロードキャストする前に数秒間待つことができます。

関連する問題