BroadcastReceiver接收一个事件的多个相同的消息

我注册了一个侦听networking事件的接收器:

<receiver android:label="NetworkConnection" android:name=".ConnectionChangeReceiver" > <intent-filter > <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> 

接收器也很简单:

 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只发送一条消息,所以在这里没有问题。

更新:

看起来像是设备特定的问题。

为了testing,我花了2个Desire HD,和4个随机Android手机(不同的Aquos模型和一些杂牌的中文东西)。 在DHD和一个随机手机上的无线连接我有3条消息,在剩下的手机上我只有一条消息。 WTF。

Related of "BroadcastReceiver接收一个事件的多个相同的消息"

接收多个广播是一个设备特定的问题。 一些电话只发送一个广播,而另一个发送2或3.但有一个工作:

假设当wifi断开连接时,你会得到断开信息,我猜测第一个是正确的,另外两个只是回声。

要知道消息已经被调用,你可以有一个静态布尔值,在连接和断开连接之间切换,并且只在你接收连接时调用你的子例程,布尔值为真。 就像是:

 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; } } } 

您还可以在静态字段中caching上次处理的连接types,并检查是否包含广播。 这样,每个连接types只能得到一个广播。

当连接types被改变时,它显然会工作。 当设备退出连接时, activeNetworkInfo将为空, 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; } } 

在我的情况下,我在onResume注册我的BroadcastReceivers,并只在onDestroy.注销它们onDestroy.

这导致每个广播接收机根据活动恢复的次数被注册3次或4次。

根据活动生命周期将广播接收器设置在正确的位置,可以让您停止接收多个令人困惑的电话。

oncreate()本身中注册您的LocalBroadcastreceiver不在onResume() 。 在onDestroy未注册

我有一个应用程序,当用户重新联机时上传数据。 由于我的广播接收机可以多次接收意图,这可能会导致数据上传不止一次。 为了处理这个问题,我使用一个服务,如果它已经在运行,它将不会做任何事情。

广播接收机:

 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) { startService(); } } } 

服务:

 public class MyService extends Service { private boolean mRunning; @Override public void onCreate() { super.onCreate(); mRunning = false; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (!mRunning) { mRunning = true; uploadTheData(); } return super.onStartCommand(intent, flags, startId); } }