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

Posted

技术标签:

【中文标题】用于互联网连接的 Android BroadcastReceiver 调用了两次【英文标题】:Android BroadcastReceiver for internet connection called twice 【发布时间】: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

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

【问题讨论】:

【参考方案1】:

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

Documentation 中声明:

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

您可以检查EXTRA_WIFI_STATE 和EXTRA_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.

【讨论】:

以上是关于用于互联网连接的 Android BroadcastReceiver 调用了两次的主要内容,如果未能解决你的问题,请参考以下文章

bindProcessToNetwork 不适用于 android 中的 ffmpeg

适用于 Android 2.2 但不适用于 Android 2.3

wemall app商城源码Android短信监听接收器

广播接收器,如 iOS 中用于检测互联网连接变化的组件

接收器用于棉花糖及以上的Wifi连接

Android MQTT 通信