【问题标题】:Android BroadcastReceiver for internet connection called twice用于互联网连接的 Android BroadcastReceiver 调用了两次
【发布时间】:2018-09-19 18:26:09
【问题描述】:

我遇到这个问题有一段时间了,注意到其他一些人也遇到了这个问题,但我无法解决它。

问题

我有一个 BroadcastReceiver,它一直在监听 Internet 的变化。因此,每当互联网连接或断开连接时,我都会在接收者的onReceive 中获得状态。

问题是它总是被调用两次。当我连接调试器并在代码中设置断点时,我可以看到它被调用了两次,但我的状态更改代码执行。当调试器未连接时,在这种情况下,我的状态更改代码根本不会执行。

我的代码

BroadcastReceiver 文件

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

}

清单意图操作

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

当我尝试在过滤器中仅使用&lt;action android:name="android.net.wifi.WIFI_STATE_CHANGED" /&gt; 时,它也出现了两次onRecieve。而当我尝试使用&lt;action android:name="android.net.conn.CONNECTIVITY_CHANGE" /&gt; 时,我根本没有来onReceive

基础活动

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

我尝试了现有的答案,但它对我不起作用。

【问题讨论】:

    标签: android android-activity broadcastreceiver android-broadcast android-networking


    【解决方案1】:

    我的猜测是 wifi 接收器被调用了两次,因为它在 enabling 状态下被调用一次,在后续 enabled 状态下被调用一次。

    Documentation 中声明:

    指示 Wi-Fi 已启用、禁用、启用、禁用或未知的广播意图操作。一个额外的提供这种状态作为一个 int。如果可用,另一个额外提供之前的状态。

    您可以检查EXTRA_WIFI_STATEEXTRA_PREVIOUS_WIFI_STATE 的值来验证是否是这种情况。

    因此,为了忽略不需要的 connecting/disconnecting 状态,您可以将您的 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);
        }
    
    }
    

    【讨论】:

    • 这里的网络状态代码是activeNetwork.isConnectedOrConnecting() 这是我发布的问题。但我也尝试了几次activeNetwork.isConnected(),但没有成功
    • 不,当我断开连接时,这两种情况都是错误的,当我连接时,第一次是错误的,第二次是正确的
    • 所以这正是我描述的情况。当您连接并且第一次调用 onReceive() 时,isConnected() 为 false,因为设备仍处于连接状态。第二次调用时,设备连接成功,所以isConnected()为真。
    • 明白了.. 那么您认为有什么可行的解决方案吗?
    • 仍然被调用了两次。第一次它总是为空。第二次价值在那里
    【解决方案2】:

    Check this link

    对于 Android 7 及更高版本,您需要在您的活动文件中注册您的接收器,而不是在清单文件中。

    因此,在您的活动的 onCreate() 中添加以下行:

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

    并在 onDestroy()

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

    在strings.xml中定义意图动作

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

    【讨论】:

    • 史诗般的答案!定义并将 R.string.action_connectivity_change 传递给 addAction() 对我有用。否则我无法导入常量。谢谢!
    【解决方案3】:

    通常,当接收被调用两次时,广播接收器被调用两次。所以请检查您是否在 2 个位置注册广播?如果是,请在简历中仅注册您的广播或创建并取消注册 onPause() 活动方法。

    例如注册广播接收器,

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

    未注册的广播接收器,例如:-

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

    希望对你有帮助。

    【讨论】:

    • 试过了。如前所述,我在 Manifest 中注册了它。现在我尝试在onResume 中从java 注册它并在onPause 中取消注册,但它没有用.. :(
    【解决方案4】:

    您应该检查 onReceive 回调中的意图操作:

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

    【讨论】:

      猜你喜欢
      • 2016-02-07
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      相关资源
      最近更新 更多