2017-01-23 21 views
0

Androidアプリで接続状態の変更を監視して判断する必要があります。そのために、私は放送受信機としての私のクラスを登録している:Androidの接続状態の変更を検出する際の競合状態

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); 
context.registerReceiver(this, filter); 

さて、接続ステータスを決定するために、次の操作を行うことができます

@Override 
public void onReceive(Context context, Intent intent) { 
    if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 
    return; 
    } 
    NetworkInfo aNetworkInfo = 
     intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 
    if (aNetworkInfo == null) { 
    return; 
    } 

    boolean isConnected = aNetworkInfo.isConnected(); 
    int networkType = aNetworkInfo.getType(); 
    // by using isConnected & networkType, get the new connectivity status.. 
} 

問題がConnectivityManager.EXTRA_NETWORK_INFOが廃止されていることです。 CONNECTIVITY_SERVICEない EXTRA_NETWORK_INFOを使用した場合、第二の実装では

@Override 
public void onReceive(Context context, Intent intent) { 
    if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { 
    return; 
    } 
    ConnectivityManager connManager = 
     (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    if (connManager == null) { 
    return; 
    } 
    NetworkInfo activeNetworkInfo = connManager.getActiveNetworkInfo(); 
    boolean isConnected = 
     (activeNetworkInfo != null) && activeNetworkInfo.isConnected(); 
    int networkType = 
     (activeNetworkInfo != null) ? activeNetworkInfo.getType() : -1; 
    // by using isConnected & networkType, get the new connectivity status.. 
} 

これは、次の質問を提起:今、あなたはそのような何か、getActiveNetworkInfo()CONNECTIVITY_SERVICEを使用することが提案されています:

競合状態になる可能性はありますか? onReceiveが非同期に呼び出されるため、接続情報サービスからネットワーク情報を取得する際に、接続状態がインテントのネットワーク情報と異なる場合があります(接続が変更される可能性があるため)。 意味を使用すると、ネットワーク情報にonReceiveがトリガーされたデータが含まれていることがわかりますが、サービスを使用しているときにネットワーク情報が異なる可能性があります...?

もしそうなら、onReceiveを引き起こした情報を得るにはどうすればよいですか? また、そうする唯一の方法がインテントを使い続けることである場合 - それは2つの真実の情報源を作りませんか? (接続サービスから1、および送信された意図から1 ...)

UPDATEが01​​

可能な競合状態の例:

誰かがすぐに無線LANに接続し、無線LANから切断。これにより、2つのインテントが送信されます(1つはWiFiに接続するためのもの、もう1つはWiFiからの接続のためのものです)。私が尋ねる可能性のある競合状態は、最初の意図(WiFiが接続されている)を取得したときに、EXTRA_NETWORK_INFOの意図がisConnected = truenetworkType = TYPE_WIFIとなることです。しかし、onReceiveが非同期に呼び出されているので、接続サービスからデータを取得すると、WiFiは既に切断されている可能性があります。isConnected = falsenetworkType = TYPE_WIFIこの呼び出しの正しい値はまだonReceiveです。またはこれはいつも速く起こりますので、onReceive ..コネクティビティサービスから適切な値を取得してください。

答えて

0

接続のステータスがアップまたはダウンしている場合、余分なを追加し、ブロードキャスト毎回接続の変更を送信していた私のソリューション、それが役に立てば幸い:

public class ConnectivityChangeReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 
    Log.i(context.getClass().getName(), " Changed connection "); 
    context.sendBroadcast(new Intent(MyApplication.ACTION_CONNECTION_CHANGED) 
      .putExtra(MyApplication.INTENT_EXTRA_CONNECTION_STATUS,NetWorkUtils.isNetworkAvailable(context))); 
}} 


public static boolean isNetworkAvailable(Context context) { 
    ConnectivityManager cm = 
      (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); 
    return activeNetwork != null && 
      activeNetwork.isConnectedOrConnecting(); 
} 

Androidのマニフェスト:だからもう一度

<receiver android:name=".ConnectivityChangeReceiver"> 
     <intent-filter> 
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
     </intent-filter> 
    </receiver> 
+0

- あなたは送信されたインテントの情報ではなく接続性サービスを使用しているため、質問が残ります(サービスからの情報はいつもインテントの情報と同じになるか、競合状態によってこの情報が異なる場合がありますか? ) – Guy

+0

うまくd ocumentationあなたはネットワークの状態を知るために余分に意図を使用することができますが、私は確かに受信時に毎回チェックするための簡単な解決策に行きました。 – AmirG

+0

CONNECTIVITY_ACTIONでhttps://developer.android.com/reference/android/net/ConnectivityManager.htmlを確認してください – AmirG