[英]BroadcastReceiver onReceive triggered when registered
I have a broadcast receiver which is being triggered the moment it's registered (and subsequently retriggered with onPause / onResume), surely this is the wrong behaviour? 我有一个广播接收器,它在注册时被触发(随后用onPause / onResume重新触发),这肯定是错误的行为? Have I missed something here?
我错过了什么吗?
class FooActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
broadcastReceiver = new FooBroadcastReceiver();
intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(connectivityReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(connectivityReceiver);
}
class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (connectivityAction(intent)) {
Log.d("footag", "onReceive");
}
}
private boolean connectivityAction(Intent intent) {
return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction());
}
}
The CONNECTIVITY_ACTION
broadcast seems to be sticky on some devices (even though the documentation implies that it is not). CONNECTIVITY_ACTION
广播似乎在某些设备上很粘(即使文档暗示它不是)。 This means that when you register the receiver it will immediately call onReceive()
with the most recently sent broadcast. 这意味着当您注册接收器时,它将立即使用最近发送的广播呼叫
onReceive()
。 Since you are registering and unregistering in onPause()
and onResume()
you will get a lot of calls to onReceive()
. 由于您在
onPause()
和onResume()
中注册和取消注册,因此您将获得对onReceive()
的大量调用。 You might want to do this in a different way. 您可能希望以不同的方式执行此操作。
Thanks for the answers! 谢谢你的回答! My solution was a result of them all, by switching to a manifest declared receiver and enabling/disabling the receiver component in onResume/onPause stopped the sticky nature of the receiver.
我的解决方案是他们所有的结果,通过切换到清单声明的接收器并在onResume / onPause中启用/禁用接收器组件停止了接收器的粘性。 And by enabling/disabling the component I can have piece of mind that I'm a second class citizen.
通过启用/禁用组件,我可以放心,我是二等公民。
@Override
protected void onResume() {
super.onResume();
setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
@Override
protected void onPause() {
super.onPause();
setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
}
private void setReceiverState(int receiverState) {
ComponentName receiver = new ComponentName(this, FooBroadcastReceiver.class);
PackageManager pm = this.getPackageManager();
pm.setComponentEnabledSetting(receiver, receiverState,
PackageManager.DONT_KILL_APP);
}
AndroidManifest.xml AndroidManifest.xml中
<receiver android:name="com.example.receiver.FooBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Here's another solution that worked for me: 这是另一个对我有用的解决方案:
class FooActivity extends Activity {
private Intent mReceiverRegisteringIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
broadcastReceiver = new FooBroadcastReceiver();
intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
}
@Override
protected void onResume() {
super.onResume();
mReceiverRegisteringIntent = registerReceiver(connectivityReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(connectivityReceiver);
}
private class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (connectivityAction(intent)) {
Log.d("footag", "onReceive");
//if mReceiverRegisteringIntent is not null, then this is the sticky
//broadcast received when registering the receiver for the first time
if (mReceiverRegisteringIntent != null) {
//set it to null for future broadcasts
mReceiverRegisteringIntent = null;
return; //do nothing
}
//logic for future broadcasts
...
}
}
private boolean connectivityAction(Intent intent) {
return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction());
}
}
}
I'm assuming that MyBroadcastReceiver
is an inner class for FooActivity
so it can access mReceiverRegisteringIntent
我假设
MyBroadcastReceiver
是一个内部类FooActivity
以便它可以访问mReceiverRegisteringIntent
remove the following two lines they won't be triggered in onPause and onResume! 删除以下两行,它们不会在onPause和onResume中触发!
registerReceiver(connectivityReceiver, intentFilter);
unregisterReceiver(connectivityReceiver);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.