【问题标题】:Broadcast Receiver calles twice广播接收器调用两次
【发布时间】:2013-04-11 20:29:07
【问题描述】:

尝试在我的应用中检查互联网连接。 我的清单有一个代码:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <receiver android:name=".MyReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
        </intent-filter>
    </receiver>

还有一个句柄类:

public class MyReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction() != null && intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE"));
    {
        Log.d("myLogs", "Network connectivity change");
        if (intent.getExtras() != null) {
            NetworkInfo ni = (NetworkInfo) intent.getExtras().get(
                    ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i("myLogs", "Network " + ni.getTypeName() + " connected");
            }
        }
        if (intent.getExtras().getBoolean(
                ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("myLogs", "There's no network connectivity");
        }
    }
}

}

在我的 Logcat 中,我得到一张像这样的图片:

04-11 23:24:48.021: D/myLogs(10261): Network connectivity change
04-11 23:24:48.021: I/myLogs(10261): Network WIFI connected
04-11 23:24:48.202: D/myLogs(10261): Network connectivity change
04-11 23:24:48.202: I/myLogs(10261): Network WIFI connected

因此,接收方呼叫了两次。为什么?所有类型的连接都存在一些问题。

【问题讨论】:

  • 也许连接的级别不同,您的 2 个日志是 2 个不同的子状态。我会注销更多信息以查看它们如何/是否不同。
  • 尝试登录if (netInfo != null &amp;&amp; netInfo.isConnected()) { Log.i("myLogs", "Network " + netInfo.getTypeName() + " connected"); } 知道有两个子状态 - isConnecting 和 isConnected,但同样的问题/

标签: android connection broadcastreceiver


【解决方案1】:

假设您在 wifi 连接时收到已连接消息,我猜第一个是正确的,而另外 2 个只是出于某种原因的回声。

要知道消息已被调用,您可以有一个静态布尔值,在连接和断开之间切换,并且仅当您收到连接并且布尔值为真时才调用您的子例程。比如:

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】:

您可能还需要通过检查接收器中的 isStickyBroadcast 来检查接收到的意图是否是粘性事件之一。如果这是真的,那么您可以忽略它并继续。接收者注册后,您会立即获得粘性广播。

http://developer.android.com/reference/android/content/BroadcastReceiver.html#isInitialStickyBroadcast%28%29

【讨论】:

    【解决方案3】:

    在文档中解释:

    设备连接的变化可能非常频繁 - 每次您在移动数据和 Wi-Fi 之间移动时都会触发此广播。因此,最好监控此情况只有在您之前暂停更新或下载以恢复它们时才广播。通常只需在开始更新之前检查 Internet 连接就足够了,如果没有,则暂停进一步的更新,直到连接恢复。”

    编辑: 忘了添加...广播接收器只是为了知道设备是否已连接有点悬停。来自相同的文档:

    ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      相关资源
      最近更新 更多