简体   繁体   English

用于互联网连接的 Android BroadcastReceiver 调用两次

[英]Android BroadcastReceiver for internet connection called twice

I am facing this issue for a while and noticed that a few other people also faced it, but I am not able to resolve it.我遇到了这个问题一段时间,并注意到其他一些人也遇到了这个问题,但我无法解决它。

The Problem问题

I have a BroadcastReceiver, which keeps listening for the internet changes.我有一个 BroadcastReceiver,它一直在监听互联网的变化。 So whenever the internet is connected or disconnected, I get the status in onReceive of the receiver.因此,无论何时连接或断开互联网,我都会在接收器的onReceive中获得状态。

The problem is it is always getting called twice.问题是它总是被调用两次。 When I connect the debugger and have the breakpoint in the code, I can see it getting called twice but my code on status change executes.当我连接调试器并在代码中设置断点时,我可以看到它被调用了两次,但我的状态更改代码会执行。 When the debugger is not connected, in that case my code on status change doesn't execute at all.当调试器未连接时,在这种情况下,我的状态更改代码根本不会执行。

My Code我的代码

BroadcastReceiver file广播接收器文件

public class ConnectivityReceiver
    extends BroadcastReceiver {

public static ConnectivityReceiverListener connectivityReceiverListener;

public ConnectivityReceiver() {
    super();
}

@Override
public void onReceive(Context context, Intent arg1) {
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();

    if (connectivityReceiverListener != null) {
        connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
    }
}

public static boolean isConnected() {
    ConnectivityManager
            cm = (ConnectivityManager) MyApplication.getInstance().getApplicationContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null
            && activeNetwork.isConnectedOrConnecting();
}


public interface ConnectivityReceiverListener {
    void onNetworkConnectionChanged(boolean isConnected);
}

}

Manifest intent action清单意图操作

<receiver
        android:name=".utils.ConnectivityReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>

here when I tried with only <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> in filter, then also it came to onRecieve twice.在这里,当我在过滤器中仅尝试<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />时,它也来到onRecieve两次。 And when I tried with <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> , then I didn't come to onReceive at all.当我尝试使用<action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> ,我根本没有来onReceive

BaseActivity基本活动

 @Override
public void onNetworkConnectionChanged(boolean isConnected) {
    setNetworkIndicator(isConnected); //THE CODE TO EXECUTE ON STATUS CHANGE
}

I tried the existing answers, and it didn't work for me.我尝试了现有的答案,但对我不起作用。

My guess here is that the wifi receiver gets called twice because it gets called once for the enabling state, and once for the followup enabled state.我的猜测是 wifi 接收器被调用两次,因为它被调用一次用于启用状态,一次用于后续启用状态。

In the Documentation it is stated that:文档中指出:

Broadcast intent action indicating that Wi-Fi has been enabled, disabled, enabling, disabling, or unknown.指示 Wi-Fi 已启用、禁用、启用、禁用或未知的广播意图操作。 One extra provides this state as an int.一个额外的提供这个状态作为一个int。 Another extra provides the previous state, if available.如果可用,另一个额外的提供以前的状态。

You can check the values of EXTRA_WIFI_STATE and EXTRA_PREVIOUS_WIFI_STATE to verify if this is the case.您可以检查EXTRA_WIFI_STATEEXTRA_PREVIOUS_WIFI_STATE的值来验证是否是这种情况。

So in order to ignore the unwanted connecting/disconnecting states, you could update your onReceive() to the following:因此,为了忽略不需要的连接/断开连接状态,您可以将onReceive()更新为以下内容:

@Override
public void onReceive(Context context, Intent arg1) {

    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

    boolean isConnected = false;
    if (activeNetwork != null){

        if (activeNetwork.getState() == NetworkInfo.State.CONNECTING || activeNetwork.getState() == NetworkInfo.State.DISCONNECTING){
            return;
        }
        isConnected = activeNetwork.isConnected();
    }

    if (connectivityReceiverListener != null) {
        connectivityReceiverListener.onNetworkConnectionChanged(isConnected);
    }

}

Check this link 检查此链接

For Android 7 and above you need to register your receiver in your activity file not in the manifest file.对于Android 7及更高版本,您需要在您的活动文件中而不是在清单文件中注册您的接收器。

So in your activity's onCreate() add the following lines:因此,在您的活动的onCreate() 中添加以下几行:

    myConnectivityReceiver = new ConnectivityReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(getResources().getString(R.string.action_connectivity_change));
    registerReceiver(myConnectivityReceiver,filter);

and in onDestroy()并在onDestroy()

  @Override
  protected void onDestroy() {
      unregisterReceiver(myConnectivityReceiver);
      super.onDestroy();
  }

define the intent action in strings.xml在 strings.xml 中定义意图操作

<string name="action_connectivity_change">android.net.conn.CONNECTIVITY_CHANGE</string>

Usually,when on Receive is called twice broadcast receiver called twice.So please check you are registering the broadcast in 2 locations?通常,当接收被调用两次广播接收器被调用两次。所以请检查您是否在 2 个位置注册广播? If yes then Please register your broadcast only in resume or create and also unregistered it onPause() method of activity.如果是,那么请在简历或创建中注册您的广播,并在活动的onPause()方法中取消注册

For Example Register Broadcast receiver,例如注册广播接收器,

LocalBroadcastManager.getInstance(this).registerReceiver(myLocalBroadcastManager, new IntentFilter(Constant.CONNECTIVITY_CHANGE));

Unregistered Broadcast Receiver like:-未注册的广播接收器,如:-

LocalBroadcastManager.getInstance(this).unregisterReceiver(myLocalBroadcastManager);

I hope it helps you.我希望它能帮助你。

You should check the intent action in the onReceive callback:您应该检查 onReceive 回调中的意图操作:

String action = arg1.getAction();
if (action != null && action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
    // do your task here.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM