2017-01-23 27 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 с getActiveNetworkInfo(), что-то вроде этого:

@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.. 
} 

В этой связи возникает следующий вопрос:

Во 2-м реализации, при использовании CONNECTIVITY_SERVICE и не EXTRA_NETWORK_INFO :

Есть ли шанс на гонку? Поскольку onReceive называется асинхронно, при получении информации о сети из службы подключения может ли состояние подключения отличаться от информации о сети в намерении (поскольку в то же время может измениться связь)? Смысл, при использовании намерения, я уверен, что информация о сети включает в себя данные, которые вызвали onReceive, но при использовании службы - информация о сети может быть другой ...?

Если да, то какой способ получить информацию, которая вызвала onReceive? Кроме того, если единственный способ сделать это - продолжать использовать намерение - не делает ли это 2 источника истины? (Одна из услуг подключения, и один из присланного намерения ...)

UPDATE:

Пример возможного состояния гонки:

Кто подключен к Wi-Fi и немедленно отключается от Wi-Fi , Это приведет к отправке 2 намерений (один для подключения к WiFi и один для отключения от Wi-Fi. На самом деле отправлено больше намерений, но я сосредоточусь на них 2). Возможное состояние гонки, о котором я спрашиваю, заключается в следующем: когда мы получим первое намерение (соединение WiFi), намерение дополнительно EXTRA_NETWORK_INFO приведет к isConnected = true и networkType = TYPE_WIFI. Но возможно ли, что когда я получу данные из службы Connectivity Service, так как onReceive называется асинхронно, Wi-Fi уже отключен, в результате чего isConnected = false и networkType = 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

проверить https://developer.android.com/reference/android/net/ConnectivityManager.html в CONNECTIVITY_ACTION – AmirG