2

这篇文章可能看起来很长.. 但它很简单。所以请帮忙。谢谢。

简而言之,每当从 Wifi 到移动连接发生变化时,我都会在广播接收器中收到 2 次消息(第一次没有找到网络)。当我从手机移到 Wifi 时,我收到了 3 次。谁能解释一下这种奇怪的行为。

我已经使用 IntentFilterConnectivityManager.CONNECTIVITY_ACTION) 实现了一个代码并将其注册到我的接收器。

IntentFilter mNetworkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);

registerReceiver(mNetworkStateReceiver , mNetworkStateFilter);


private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() 
          {

            @Override
            public void onReceive(Context context, Intent intent) 
            {
                  //The Network State has Been Changed
                  Log.d(TAG, "CHANGE HAPPENED" );

                 if (networkInfo != null)
        {
            Log.d(TAG, "Connected To: " + networkInfo.getTypeName());
            Log.d(TAG, "NUMBER: " + networkInfo.getType());
            Log.d(TAG, "isConnectedOrConnecting: " + networkInfo.isConnectedOrConnecting());
            Log.d(TAG, "isConnected: " + networkInfo.isConnected());
            Log.d(TAG, "isFailover: " + networkInfo.isFailover());
            Log.d(TAG, "Reason :" + networkInfo.getReason());
            Log.d(TAG, "Details " + networkInfo.getDetailedState() );


            boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
            String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
            boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);



            Log.d(TAG, "noConnectivity: " + noConnectivity);
            Log.d(TAG, "reason: " + reason);

            Log.d(TAG,"DONE");

        }       


            }
      };

我观察到以下行为。谁能解释一下发生这种情况的原因。

最初,我的设备连接到 Wifi。

APK 现在已部署在设备上。

我的 Logcat 条目是 D/MainActivity(32005): CHANGE HAPPENED D/MainActivity(32005): Connected to WIFI

这是可以理解的。

现在路由器已关闭。所以现在设备尝试连接到 4G。现在,Logcat 条目如下。

D/MainActivity(32005):发生变化 D/MainActivity(32005):发生变化 D/MainActivity(32005):连接到移动设备

可能这可以归因于第一个连接断开的事实,这导致打印发生了变化,但没有显示“已连接到”消息。然后与 Mobile 建立连接,导致 Connected to Mobile 发生另一个变化。

现在路由器再次打开。

但这次 logcat 报告 D/MainActivity(32005): CHANGE HAPPENED

D/MainActivity(32005):连接到WIFI

D/MainActivity(32005):发生变化

D/MainActivity(32005):连接到WIFI

D/MainActivity(32005):发生变化

D/MainActivity(32005):连接到WIFI

我无法理解为什么 Logcat 会报告此消息 3 次。谁能帮我理解这种行为。

这是我的清单文件。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wififourghandoff"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这是我的观察。

序列是否如下所示:

Wifi 到手机: 1. Network Info 为 NULL 2. Netowrk Info 对象存在并且“reason(networkInfo.getReason()”是 dataEnabled。

从手机到 Wifi: 1. 收到广播消息。2. Netowrk Info 对象存在且“reason(networkInfo.getReason()”为 dataDisabled。3. NetworkInfo 存在且“reason(networkInfo.getReason()”为空

我的设备最初是在 WIFI 上预占我的 Logcat

D/MainActivity(880):发生变化

D/MainActivity(880):连接到:WIFI

D/MainActivity(880):编号:1

D/MainActivity(880):isConnectedOrConnecting:真

D/MainActivity(880):isConnected:真

D/MainActivity(880):isFailover:假

D/MainActivity(880):原因:空

D/MainActivity(880):详细信息已连接

D/MainActivity(880):无连接性:假

D/MainActivity(880):原因:空

D/MainActivity(880):完成

现在 WIFI 已关闭。所以现在我的设备移动到移动设备。以下是Logcat。

D/MainActivity(880):发生变化

D/MainActivity(880):发生变化

D/MainActivity(880):连接到:移动

D/MainActivity(880):编号:0

D/MainActivity(880):isConnectedOrConnecting:真

D/MainActivity(880):isConnected:真

D/MainActivity(880):isFailover:真

D/MainActivity(880):原因:dataEnabled

D/MainActivity(880):详细信息已连接

D/MainActivity(880):无连接性:假

D/MainActivity(880):原因:dataEnabled

D/MainActivity(880):完成

现在我的 WIFI 已打开。我的设备又回到了 Wifi。

D/MainActivity(880):发生变化

D/MainActivity(880):连接到:WIFI

D/MainActivity(880):编号:1

D/MainActivity(880):isConnectedOrConnecting:真

D/MainActivity(880):isConnected:真

D/MainActivity(880):isFailover:假

D/MainActivity(880):原因:空

D/MainActivity(880):详细信息已连接

D/MainActivity(880):无连接性:假

D/MainActivity(880):原因:空

D/MainActivity(880):完成

D/MainActivity(880):发生变化

D/MainActivity(880):连接到:WIFI

D/MainActivity(880):编号:1

D/MainActivity(880):isConnectedOrConnecting:真

D/MainActivity(880):isConnected:真

D/MainActivity(880):isFailover:假

D/MainActivity(880):原因:空

D/MainActivity(880):详细信息已连接

D/MainActivity(880):无连接性:假

D/MainActivity(880):原因:dataDisabled

D/MainActivity(880):完成

D/MainActivity(880):发生变化

D/MainActivity(880):连接到:WIFI

D/MainActivity(880):编号:1

D/MainActivity(880):isConnectedOrConnecting:真

D/MainActivity(880):isConnected:真

D/MainActivity(880):isFailover:假

D/MainActivity(880):原因:空

D/MainActivity(880):详细信息已连接

D/MainActivity(880):无连接性:假

D/MainActivity(880):原因:空

D/MainActivity(880):完成

谢谢和问候, 尤维

4

2 回答 2

0

好吧,您可以检查NetworkInfo哪些是作为额外发送的。

可能是它正在接收故障转移消息,如文档中所述- 当它第一次失败时,接收到消息然后再次成功连接。

对于连接丢失,如果连接管理器正在尝试连接(或已经连接)到另一个网络,则新网络的 NetworkInfo 也作为额外的传递。这让广播的任何接收者都知道他们不应该告诉用户没有数据流量是可能的。相反,接收者应该期待很快另一个广播,表明故障转移尝试成功(因此仍然存在整体数据连接),或者故障转移尝试失败,这意味着所有连接都已丢失。

于 2012-08-13T22:07:34.990 回答
0

我认为如果您记录Extra内容,则行为可能更有意义:

http://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION

网络连接发生了变化。连接已建立或丢失。受影响网络的 NetworkInfo 作为额外发送;应该咨询它以查看发生了什么样的连接事件。

如果这是从断开的网络故障转移的结果,则 FAILOVER_CONNECTION 布尔额外设置为 true。

对于连接丢失,如果连接管理器正在尝试连接(或已经连接)到另一个网络,则新网络的 NetworkInfo 也作为额外的传递。这让广播的任何接收者都知道他们不应该告诉用户没有数据流量是可能的。相反,接收者应该期待很快另一个广播,表明故障转移尝试成功(因此仍然存在整体数据连接),或者故障转移尝试失败,这意味着所有连接都已丢失。

对于断开连接事件,如果根本没有连接的网络,则布尔额外的 EXTRA_NO_CONNECTIVITY 设置为 true。

我对启用 WiFi 时的三个事件的解释:

  1. 第一个事件只是通知您 WiFi 已启用。
  2. 第二个事件是通知您蜂窝网络连接已禁用并且有另一个可用网络 (WiFi)。这是具有 NetworkInfo 的事件。
  3. 这本质上是事件 1 的副本。每当 NetworkInfo 发生断开连接事件时,Android 承诺它将跟进 NetworkInfo 中网络的连接成功/失败事件

所以,这对你来说有点多余,但这是 Android 的正常行为。以下是我实验的一些日志:

    08-14 10:58:04.498: DEBUG/WiFiBroadcastReceiver(9161): Bundle[{networkInfo=NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true, inetCondition=0}]
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Bundle[{extraInfo=VZWINTERNET, otherNetwork=NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true, reason=dataDisabled, networkInfo=NetworkInfo: type: mobile[LTE], state: DISCONNECTED/DISCONNECTED, reason: dataDisabled, extra: VZWINTERNET, roaming: false, failover: false, isAvailable: true, inetCondition=0}]
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): ***********Network Info ******
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Connected To: WIFI
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Network Type: 1
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): isConnectedOrConnecting: true
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): isConnected: true
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): isFailover: false
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Reason :null
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Details: CONNECTED
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): noConnectivity: false
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): reason: dataDisabled
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): ******************************
    08-14 10:58:04.779: DEBUG/WiFiBroadcastReceiver(9161): Bundle[{networkInfo=NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true, inetCondition=0}]
于 2012-08-13T22:08:10.057 回答