用于互联网连接的 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>
当我尝试在过滤器中仅使用<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
时,它也出现了两次onRecieve
。而当我尝试使用<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
时,我根本没有来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