BroadcastReceiver onReceive запускается при регистрации
У меня есть широковещательный приемник, который запускается в тот момент, когда он зарегистрировался (и впоследствии перезапущен с onPause/onResume), неужели это неправильное поведение? Я что-то пропустил?
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());
}
}
Ответы
Ответ 1
Спасибо за ответы! Мое решение было результатом их всех, переключившись на манифест объявленного приемника и включив/отключив компонент приемника в onResume/onPause, остановив липкий характер получателя. И, включив/отключив компонент, я могу подумать, что я гражданин второго сорта.
@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
<receiver android:name="com.example.receiver.FooBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Ответ 2
Передача CONNECTIVITY_ACTION
, похоже, липкая на некоторых устройствах (хотя документация подразумевает, что это не так). Это означает, что когда вы зарегистрируете приемник, он немедленно вызовет onReceive()
с самой последней переданной трансляцией. Поскольку вы регистрируетесь и не регистрируетесь в onPause()
и onResume()
, вы получите много вызовов onReceive()
. Возможно, вы захотите сделать это по-другому.
Ответ 3
Здесь другое решение, которое сработало для меня:
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());
}
}
}
Я предполагаю, что MyBroadcastReceiver
является внутренним классом для FooActivity
, поэтому он может получить доступ к mReceiverRegisteringIntent
Ответ 4
удалите следующие две строки, они не будут запущены в onPause и onResume!
registerReceiver(connectivityReceiver, intentFilter);
unregisterReceiver(connectivityReceiver);