当前位置:  开发笔记 > Android > 正文

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

如何解决《BroadcastReceiver为一个事件接收多个相同的消息》经验,为你挑选了2个好方法。

我注册了一个监听网络事件的接收器:


    
        
    

接收器也很简单:

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.



1> brianestey..:

接收多个广播是设备特定的问题.有些手机只发送一个广播而其他手机发送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;
        }
    }
}


谢谢!这是非常好的和简单的想法.您需要注意两件事.首先 - 在某处存储"firstConnect",例如在共享首选项中存储,其次是当您从3G更改为WiFi时,没有实际断开连接,因此最好分别处理3G和WiFi事件.

2> Aleksandar I..:

您还可以在静态字段中缓存上次处理的连接类型,并检查进入的广播.这样,每种连接类型只能获得一个广播.

当连接类型改变时,它显然会起作用.当设备脱离连接时activeNetworkInfo将为null,并且currentTypeNO_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;
        }
}

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有