52

私のアプリでは、タグBroadcastReceiverを介してコンポーネントとして起動され、インテントをフィルタリングしています。<receiver>android.net.conn.CONNECTIVITY_CHANGE

私の目標は、Wifi接続がいつ確立されたかを知ることだけなので、私がやっていることonReceive()は次のとおりです。

NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) {
    // Wifi is connected
}

正常に動作しますが、Wifi 接続が確立されると、常に約 1 秒以内に 2 つの同一の意図が得られるようです。ConnectivityManagerインテントとから取得できる情報を調べようとしましたWifiManagerが、2 つのインテントを区別するものは何も見つかりません。

BroadcastReceiverログを見ると、同じ 2 つのインテントを受信するものも少なくとも 1 つあります。

Android 2.2を搭載したHTC Desireで実行されています

Wifi 接続時に「重複した」意図を取得しているように見える理由、または 2 つの違いは何ですか?

4

14 に答える 14

63

注:最近の最新の回答については、以下の回答を参照してください。

たくさんのグーグルとデバッグの後、これがWifiが接続されているか切断されているかを判断する正しい方法だと思います。

onReceive()BroadcastReceiverのメソッド:

public void onReceive(final Context context, final Intent intent) {

if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    NetworkInfo networkInfo =
        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
    if(networkInfo.isConnected()) {
        // Wifi is connected
        Log.d("Inetify", "Wifi is connected: " + String.valueOf(networkInfo));
    }
} else if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
    NetworkInfo networkInfo =
        intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
    if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI &&
        ! networkInfo.isConnected()) {
        // Wifi is disconnected
        Log.d("Inetify", "Wifi is disconnected: " + String.valueOf(networkInfo));
    }
}
}

AndroidManifest.xmlの次のレシーバー要素と一緒に

<receiver android:name="ConnectivityActionReceiver"
    android:enabled="true" android:label="ConnectivityActionReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
        <action android:name="android.net.wifi.STATE_CHANGE"/>
    </intent-filter>
</receiver>

いくつかの説明:

  • のみを検討するConnectivityManager.CONNECTIVITY_ACTION場合、Wifiが接続すると、常に同一のNetworkInfoインスタンスを含む2つのインテント(getType()== TYPE_WIFIとisConnected()== trueの両方)が取得されます。この質問で説明されている問題です。

  • のみを使用するWifiManager.NETWORK_STATE_CHANGED_ACTION場合、Wifiが切断されたときにブロードキャストされるインテントはありませんが、異なるNetworkInfoインスタンスを含む2つのインテントがあり、Wifiが接続されているときに1つのイベントを判別できます。

intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO)注: nullが返された単一のクラッシュレポート(NPE)を受け取りました。したがって、発生することが非常にまれであるように思われる場合でも、nullチェックを追加することをお勧めします。

乾杯、トルステン

于 2011-05-04T21:31:47.420 に答える
12

を聞いているWifiManager.NETWORK_STATE_CHANGED_ACTION場合は、2 つの方法があるため、これを 2 回受け取ります。NetworkInfo

  • isConnectedOrConnecting()
  • isConnected()

1回目のisConnectedOrConnecting()返品trueisConnected() false
2回目isConnectedOrConnecting()isConnected()返品true

乾杯

于 2011-09-06T20:27:52.140 に答える
4

Torsten のコードを更新し、WIFI が切断されたときに、単一の適切なブロードキャストのみが処理されるようにしました。

確認には NetworkInfo.getDetailedState() == DetailedState.DISCONNECTED を使用しました。

public void onReceive(final Context context, final Intent intent) {
    if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
        NetworkInfo networkInfo = intent
            .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        if (networkInfo.isConnected()) {
            // Wifi is connected
            Log.d("Inetify","Wifi is connected: " + String.valueOf(networkInfo));
        }
    } else if (intent.getAction().equals(
        ConnectivityManager.CONNECTIVITY_ACTION)) {
        NetworkInfo networkInfo = intent
            .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        if (networkInfo.getDetailedState() == DetailedState.DISCONNECTED) {
            // Wifi is disconnected
            Log.d("Inetify","Wifi is disconnected: "+String.valueOf(networkInfo));
        }
    }
}
于 2013-06-25T06:29:07.923 に答える
3

アクティビティをインテント リスナーとして登録した場合、同じメッセージを 2 回受け取ります。具体的には、パッケージ レベル (XML) でリッスンするか、プログラム レベルでリッスンするかを選択する必要があります。

ブロードキャスト レシーバーのクラスを設定してリッスンをアタッチし、インテント フィルターをアクティビティーにアタッチすると、メッセージは 2 回複製されます。

これで問題が解決することを願っています。

于 2011-05-04T21:49:03.930 に答える
0

私がそれを処理した方法は、ネットワークの状態を保存し、それを比較して変化があるかどうかを確認することでした.

public class ConnectivityChangedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        boolean previouslyConnected = MyApp.getInstance().isNetworkPreviouslyConnected();
        boolean currentlyConnected = MyApp.getInstance().isNetworkConnected();

        if (previouslyConnected != currentlyConnected) {
            // do something and reset
            MyApp.getInstance().resetNetworkPreviouslyConnected();
        }
    }

}

これがあなたのアプローチでonResumeある場合は、現在の値を保持するために、フラグメントまたはアクティビティでリセットすることが重要です。

@Override
public void onResume() {
    super.onResume();
    MyApp.getInstance().resetNetworkPreviouslyConnected();
}

BaseFragmentアプリ内のすべてのフラグメントの親である でそれを行いました。

于 2015-03-23T18:57:12.700 に答える
0

インテントから networkType を確認し、activeNetworkInfo.getType() を比較します

                 Bundle bundle = intent.getExtras();
                 ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                 NetworkInfo ni = manager.getActiveNetworkInfo();

                 if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                     if(bundle.getInt("networkType") == ni.getType()) {
                         // active network intent
                     }
                 }
于 2016-09-29T01:09:55.913 に答える
-2

アクション「android.net.conn.CONNECTIVITY_CHANGE」のみをリッスンします。接続が確立または破棄されるたびにブロードキャストされます。

接続が確立すると、「android.net.wifi.STATE_CHANGE」がブロードキャストされます。したがって、2 つのトリガーを取得します。

楽しみ!

于 2011-10-19T02:33:57.243 に答える