This page describes how Android selects between concurrently available networks. This network selection mechanism affects how Android fulfills app and system network requests, and influences how the default network for an app is chosen.
Network selection behavior
This section describes the network selection behavior for devices running Android 12 or higher and for devices running Android 11 and lower.
For devices running Android 12 or higher, Android uses
class to select between available networks. This class contains a number of
flags required to make policy decisions. Each flag semantically represents an
attribute of a network that's important for network selection.
A network agent
flag to specify that the network is preferred when multiple networks of the same
transport are present. A typical example of this is a dual-SIM device with a
switch in Settings to let the user choose which of the SIM cards to use by
default. Within a given transport, Android prefers a network with the
flag over a network without the flag.
A network agent uses the
flag to identify a network that is expected to disconnect soon. A typical
example of this is when a Wi-Fi network quality degrades as a user walks out of
range of the network. Android avoids using a network with this flag if another
network without this flag is available. Each individual network agent can
determine when a network degrades enough to be considered exiting.
NetworkScore class also allows a network agent to declare that a network
be kept up using the
flag and the
flag is useful for prospective networks allowing a network agent to bring up a
network on a secondary Wi-Fi STA without making it the primary network until the
network's performance is evaluated. If a network agent doesn't declare this
flag, prospective networks are torn down for not servicing any request before
the agent has a chance to evaluate a network's performance.
If two networks can serve a given request and are equivalent from a policy point of view, the selection prefers the network that is currently serving the request. If no network is serving the request, it chooses one of the two, after which this network continues to be preferred until policy flags change.
The implementation for the network selection feature is in the
in AOSP. The policy logic for network selection is found in the
class and its helper classes. This means that device manufacturers can't
directly customize the network selection code but instead must use the flags in
to convey required information about networks.
For devices running Android 11 or lower, Android performs network selection
based on a simple integer sent from the implementations of a network agent
For each request, Android selects the network with the highest numeric score
that can satisfy the request. This numeric score is composed of the integer sent
by the network agent plus additional bonuses or penalties given based on a
number of conditions such as whether the network is validated or whether the
network is a VPN. Individual network agents synchronize with each other in order
to make policy decisions.
If two networks can serve a given request and have the same numeric score, the behavior is undefined.
The central class for the network selection feature is
This class contains the API and documentation of the available flags and
NetworkScore class must be built through its builder class and be passed
upon initialization. Network scores can be updated at any time using the
Network agent implementation examples
AOSP includes example implementations of various network agents. The following are example implementations:
DcNetworkAgent: Uses network score to communicate policy for mobile networks
ClientModeImpl.WifiNetworkAgent: Uses network score to communicate policy for Wi-Fi networks. This implementation includes backward compatibility with the legacy integer for network score using the
Devices upgrading to Android 12
Device manufacturers upgrading their devices to
Android 12 must modify their network agent
implementations to use the
NetworkScore class. The legacy integer used in
Android 11 or lower is passed in
NetworkScore but is only used
for logging and non-regression purposes in Android 12.
In Android 12, device manufacturers must express
desired changes using
NetworkScore flags. The Connectivity Mainline module
then uses the flags to make the network selection decision. Devices
manufacturers using code for Android 11 or lower but building against the
implementation in Android 12 can expect build errors
as the methods for updating the legacy integer were removed in
For network agents that use the internal
class, they must express their score filter in a
representing the strongest score of a network the factory can create. This is
because in Android 12 the
NetworkFactory class only
passes requests that match the score filters declared to
instead of all requests in Android 11 and lower.
We recommend passing a filter for easier implementation and battery savings so
that not all requests are passed to
NetworkFactory. However, if your custom
implementation requires that all requests be passed to
NetworkFactory, you can
instead of the regular
method. If using this method, we recommend passing a score filter that
represents most accurately the best score the factory can create in order to
save battery by not evaluating requests that the factory can't fulfill.
To verify the behavior of network selection on an Android device, use the following tests:
Incorrect implementation might result in unexpected networks being returned to
apps in response to their use of
including selecting the default network of the device (the network the system
sends to the app when they use a network callback with
Another possible issue with incorrect implementation is severe battery drain caused by a network agent being brought up with a score that doesn't let it qualify for any request and being torn down immediately after. If the agent is brought up and torn down repeatedly, this could use up a lot of battery.