我注册了一个监听网络事件的接收器:
接收器也很简单:
public class ConnectionChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetInfo != null) { Log.v("@@@","Receiver : " + activeNetInfo); } else { Log.v("@@@","Receiver : " + "No network"); } } }
问题是,当连接Wifi时,我连续收到3条相同的消息,如下所示:
Receiver : NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true Receiver : NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true Receiver : NetworkInfo: type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true
它们都是"连接/连接"(它们不应该像CONNECTING/OBTAINING_IPADDR等),所以问题是如何判断它何时真正连接?当wifi实际连接时我有一些我想做的例程,我不希望连续三次调用它们.
PS:3G只发送一条消息,所以这里没问题.
更新:
似乎是设备特定的问题.
为了测试我拿了2个Desire HD和4个随机Android手机(不同的Aquos型号和一些无名的中文内容).在DHD和wifi上的一个随机电话连接上我收到3条消息,在剩下的手机上我只收到一条消息.WTF.
接收多个广播是设备特定的问题.有些手机只发送一个广播而其他手机发送2个或3个.但有一个解决方法:
假设你在断开wifi时得到断开连接的消息,我猜第一个是正确的,另外两个只是因为某种原因的回声.
要知道消息已被调用,你可以有一个静态布尔值,它在connect和disconnect之间切换,只在你收到一个连接并且boolean为true时调用你的子例程.就像是:
public class ConnectionChangeReceiver extends BroadcastReceiver { private static boolean firstConnect = true; @Override public void onReceive(Context context, Intent intent) { final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); if (activeNetInfo != null) { if(firstConnect) { // do subroutines here firstConnect = false; } } else { firstConnect= true; } } }
您还可以在静态字段中缓存上次处理的连接类型,并检查进入的广播.这样,每种连接类型只能获得一个广播.
当连接类型改变时,它显然会起作用.当设备脱离连接时activeNetworkInfo
将为null,并且currentType
将NO_CONNECTION_TYPE
与默认情况一样.
public class ConnectivityReceiver extends BroadcastReceiver { /** The absence of a connection type. */ private static final int NO_CONNECTION_TYPE = -1; /** The last processed network type. */ private static int sLastType = NO_CONNECTION_TYPE; @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); final int currentType = activeNetworkInfo != null ? activeNetworkInfo.getType() : NO_CONNECTION_TYPE; // Avoid handling multiple broadcasts for the same connection type if (sLastType != currentType) { if (activeNetworkInfo != null) { boolean isConnectedOrConnecting = activeNetworkInfo.isConnectedOrConnecting(); boolean isWiFi = ConnectivityManager.TYPE_WIFI == currentType; boolean isMobile = ConnectivityManager.TYPE_MOBILE == currentType; // TODO Connected. Do your stuff! } else { // TODO Disconnected. Do your stuff! } sLastType = currentType; } }