From 1c633fc89bae9bf0af6fe643ac7ad2e744f27bed Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 8 Dec 2009 19:45:14 -0800 Subject: [PATCH] Implement API to have new broadcasts replace existing broadcasts. Use this in various places where it should serve no purpose to deliver both broadcasts. This is intended to reduce somewhat the flurry of broadcasts that we churn through during boot. --- api/current.xml | 11 +++++ core/java/android/content/Intent.java | 20 +++++++-- .../server/search/SearchManagerService.java | 5 ++- media/java/android/media/AudioService.java | 14 +++--- .../android/server/AlarmManagerService.java | 10 +++-- .../com/android/server/BatteryService.java | 3 +- .../android/server/ConnectivityService.java | 25 +++++------ .../java/com/android/server/DockObserver.java | 1 + .../server/InputMethodManagerService.java | 1 + .../com/android/server/TelephonyRegistry.java | 5 +++ .../server/am/ActivityManagerService.java | 45 ++++++++++++++++--- .../android/internal/telephony/IccCard.java | 1 + .../internal/telephony/PhoneProxy.java | 1 + .../cdma/CdmaServiceStateTracker.java | 3 ++ .../telephony/gsm/GsmServiceStateTracker.java | 3 ++ .../android/net/wifi/WifiStateTracker.java | 6 ++- 16 files changed, 117 insertions(+), 37 deletions(-) diff --git a/api/current.xml b/api/current.xml index 13edee3952b37..1ab1f5e37bf62 100644 --- a/api/current.xml +++ b/api/current.xml @@ -37304,6 +37304,17 @@ visibility="public" > + + This flag is most typically used with sticky broadcasts, which + * only care about delivering the most recent values of the broadcast + * to their receivers. + */ + public static final int FLAG_RECEIVER_REPLACE_PENDING = 0x20000000; /** * If set, when sending a broadcast before boot has completed only * registered receivers will be called -- no BroadcastReceiver components @@ -2411,14 +2425,14 @@ public class Intent implements Parcelable { * * @hide */ - public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x20000000; + public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x10000000; /** * Set when this broadcast is for a boot upgrade, a special mode that * allows the broadcast to be sent before the system is ready and launches * the app process with no providers running in it. * @hide */ - public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x10000000; + public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x08000000; /** * @hide Flags that can't be changed with PendingIntent. diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index 6e8b7eea31470..f9a0b93c97ba2 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -150,8 +150,9 @@ public class SearchManagerService extends ISearchManager.Stub { * Informs all listeners that the list of searchables has been updated. */ void broadcastSearchablesChanged() { - mContext.sendBroadcast( - new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED)); + Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + mContext.sendBroadcast(intent); } // diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index b41f3e29f3ad4..e5837eef237d3 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -892,13 +892,13 @@ public class AudioService extends IAudioService.Stub { private void broadcastRingerMode() { // Send sticky broadcast - if (ActivityManagerNative.isSystemReady()) { - Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION); - broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode); - long origCallerIdentityToken = Binder.clearCallingIdentity(); - mContext.sendStickyBroadcast(broadcast); - Binder.restoreCallingIdentity(origCallerIdentityToken); - } + Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION); + broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode); + broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_REPLACE_PENDING); + long origCallerIdentityToken = Binder.clearCallingIdentity(); + mContext.sendStickyBroadcast(broadcast); + Binder.restoreCallingIdentity(origCallerIdentityToken); } private void broadcastVibrateSetting(int vibrateType) { diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java index 8d86219c9db69..18a5615af44ba 100644 --- a/services/java/com/android/server/AlarmManagerService.java +++ b/services/java/com/android/server/AlarmManagerService.java @@ -127,8 +127,9 @@ class AlarmManagerService extends IAlarmManager.Stub { mTimeTickSender = PendingIntent.getBroadcast(context, 0, new Intent(Intent.ACTION_TIME_TICK).addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0); - mDateChangeSender = PendingIntent.getBroadcast(context, 0, - new Intent(Intent.ACTION_DATE_CHANGED), 0); + Intent intent = new Intent(Intent.ACTION_DATE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + mDateChangeSender = PendingIntent.getBroadcast(context, 0, intent, 0); // now that we have initied the driver schedule the alarm mClockReceiver= new ClockReceiver(); @@ -272,6 +273,7 @@ class AlarmManagerService extends IAlarmManager.Stub { if (timeZoneWasChanged) { Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time-zone", zone.getID()); mContext.sendBroadcast(intent); } @@ -609,7 +611,9 @@ class AlarmManagerService extends IAlarmManager.Stub { if ((result & TIME_CHANGED_MASK) != 0) { remove(mTimeTickSender); mClockReceiver.scheduleTimeTickEvent(); - mContext.sendBroadcast(new Intent(Intent.ACTION_TIME_CHANGED)); + Intent intent = new Intent(Intent.ACTION_TIME_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + mContext.sendBroadcast(intent); } synchronized (mLock) { diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java index e98fa99835a99..bdebc8d81ee90 100644 --- a/services/java/com/android/server/BatteryService.java +++ b/services/java/com/android/server/BatteryService.java @@ -327,7 +327,8 @@ class BatteryService extends Binder { private final void sendIntent() { // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY + | Intent.FLAG_RECEIVER_REPLACE_PENDING); try { mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel); } catch (RemoteException e) { diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 27b631e4929ba..77884a4444c0c 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -98,7 +98,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { private List mFeatureUsers; private boolean mSystemReady; - private ArrayList mDeferredBroadcasts; + private Intent mInitialBroadcast; private static class NetworkAttributes { /** @@ -786,6 +786,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); if (info.isFailover()) { intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); @@ -885,6 +886,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void sendConnectedBroadcast(NetworkInfo info) { Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); if (info.isFailover()) { intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true); @@ -922,6 +924,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); if (getActiveNetworkInfo() == null) { intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true); @@ -941,26 +944,20 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void sendStickyBroadcast(Intent intent) { synchronized(this) { - if (mSystemReady) { - mContext.sendStickyBroadcast(intent); - } else { - if (mDeferredBroadcasts == null) { - mDeferredBroadcasts = new ArrayList(); - } - mDeferredBroadcasts.add(intent); + if (!mSystemReady) { + mInitialBroadcast = new Intent(intent); } + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mContext.sendStickyBroadcast(intent); } } void systemReady() { synchronized(this) { mSystemReady = true; - if (mDeferredBroadcasts != null) { - int count = mDeferredBroadcasts.size(); - for (int i = 0; i < count; i++) { - mContext.sendStickyBroadcast(mDeferredBroadcasts.get(i)); - } - mDeferredBroadcasts = null; + if (mInitialBroadcast != null) { + mContext.sendStickyBroadcast(mInitialBroadcast); + mInitialBroadcast = null; } } } diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index 2fff54c05777a..6ea50c7edfbfe 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -179,6 +179,7 @@ class DockObserver extends UEventObserver { } // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); // Check if this is Bluetooth Dock diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index a64cb1acd1a2b..405dc2e34ca06 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -949,6 +949,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (ActivityManagerNative.isSystemReady()) { Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("input_method_id", id); mContext.sendBroadcast(intent); } diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java index 47cb6adce87a4..3bee40c430b1d 100644 --- a/services/java/com/android/server/TelephonyRegistry.java +++ b/services/java/com/android/server/TelephonyRegistry.java @@ -485,6 +485,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); Bundle data = new Bundle(); state.fillInNotifierBundle(data); intent.putExtras(data); @@ -502,6 +503,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); Bundle data = new Bundle(); signalStrength.fillInNotifierBundle(data); intent.putExtras(data); @@ -523,6 +525,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString()); if (!TextUtils.isEmpty(incomingNumber)) { intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); @@ -537,6 +540,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { // status bar takes care of that after taking into account all of the // required info. Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString()); if (!isDataConnectivityPossible) { intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true); @@ -559,6 +563,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastDataConnectionFailed(String reason) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.FAILURE_REASON_KEY, reason); mContext.sendStickyBroadcast(intent); } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index fc47f93010374..1eeb49f6588de 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -11844,6 +11844,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // pm is in same process, this will never happen. } + final boolean replacePending = + (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; + + if (DEBUG_BROADCAST) Log.v(TAG, "Enqueing broadcast: " + intent.getAction() + + " replacePending=" + replacePending); + int NR = registeredReceivers != null ? registeredReceivers.size() : 0; if (!ordered && NR > 0) { // If we are not serializing this broadcast, then send the @@ -11856,8 +11862,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (DEBUG_BROADCAST) Log.v( TAG, "Enqueueing parallel broadcast " + r + ": prev had " + mParallelBroadcasts.size()); - mParallelBroadcasts.add(r); - scheduleBroadcastsLocked(); + boolean replaced = false; + if (replacePending) { + for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { + if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { + if (DEBUG_BROADCAST) Log.v(TAG, + "***** DROPPING PARALLEL: " + intent); + mParallelBroadcasts.set(i, r); + replaced = true; + break; + } + } + } + if (!replaced) { + mParallelBroadcasts.add(r); + scheduleBroadcastsLocked(); + } registeredReceivers = null; NR = 0; } @@ -11940,8 +11960,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int seq = r.intent.getIntExtra("seq", -1); Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); } - mOrderedBroadcasts.add(r); - scheduleBroadcastsLocked(); + boolean replaced = false; + if (replacePending) { + for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { + if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { + if (DEBUG_BROADCAST) Log.v(TAG, + "***** DROPPING ORDERED: " + intent); + mOrderedBroadcasts.set(i, r); + replaced = true; + break; + } + } + } + if (!replaced) { + mOrderedBroadcasts.add(r); + scheduleBroadcastsLocked(); + } } return BROADCAST_SUCCESS; @@ -12837,7 +12871,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY + | Intent.FLAG_RECEIVER_REPLACE_PENDING); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, false, false, MY_PID, Process.SYSTEM_UID); if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 0f766334ba535..6eea46eb67ed8 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -468,6 +468,7 @@ public abstract class IccCard { public void broadcastIccStateChangedIntent(String value, String reason) { Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.PHONE_NAME_KEY, mPhone.getPhoneName()); intent.putExtra(INTENT_KEY_ICC_STATE, value); intent.putExtra(INTENT_KEY_LOCKED_REASON, reason); diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index c693ae1e595c8..3eadd81ee6539 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -134,6 +134,7 @@ public class PhoneProxy extends Handler implements Phone { //Send an Intent to the PhoneApp that we had a radio technology change Intent intent = new Intent(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Phone.PHONE_NAME_KEY, mActivePhone.getPhoneName()); ActivityManagerNative.broadcastStickyIntent(intent, null); break; diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index c3d49402e2fb0..8698b38544c7a 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -597,6 +597,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { || !TextUtils.equals(spn, curSpn) || !TextUtils.equals(plmn, curPlmn)) { Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn); intent.putExtra(Intents.EXTRA_SPN, spn); intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); @@ -1523,6 +1524,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); alarm.setTimeZone(zoneId); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time-zone", zoneId); phone.getContext().sendStickyBroadcast(intent); } @@ -1536,6 +1538,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { private void setAndBroadcastNetworkSetTime(long time) { SystemClock.setCurrentTimeMillis(time); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time", time); phone.getContext().sendStickyBroadcast(intent); } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index 8140654c4a201..f82474c079c3c 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -557,6 +557,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { boolean showPlmn = (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN; Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn); intent.putExtra(Intents.EXTRA_SPN, spn); intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); @@ -1488,6 +1489,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); alarm.setTimeZone(zoneId); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time-zone", zoneId); phone.getContext().sendStickyBroadcast(intent); } @@ -1501,6 +1503,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { private void setAndBroadcastNetworkSetTime(long time) { SystemClock.setCurrentTimeMillis(time); Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra("time", time); phone.getContext().sendStickyBroadcast(intent); } diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 0b9c69c094112..9d8f730849c71 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -973,7 +973,8 @@ public class WifiStateTracker extends NetworkStateTracker { mDisconnectExpected = false; intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable)newState); if (failedToAuthenticate) { if (LOCAL_LOGD) Log.d(TAG, "Failed to authenticate, disabling network " + networkId); @@ -1443,7 +1444,8 @@ public class WifiStateTracker extends NetworkStateTracker { private void sendNetworkStateChangeBroadcast(String bssid) { Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT + | Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo); if (bssid != null) intent.putExtra(WifiManager.EXTRA_BSSID, bssid);