This page describes how Android selects among concurrently available networks. This network selection mechanism affects how Android fulfills app and system network requests and influences how Android chooses the default network for an app.
Network selection behavior
This section describes network selection behavior for devices running Android 12 or higher and for devices running Android 11 (API level 30) and lower.
Android 12
For devices running Android 12 or higher, Android uses
the NetworkScore
class to select among available networks. This class
contains flags that make policy decisions. Each flag represents a network
attribute that is important for network selection.
A network agent (NetworkAgent
) uses the POLICY_TRANSPORT_PRIMARY
flag to specify that Android prefers the network if multiple networks of the
same transport are present. For example, a dual-SIM device has a switch in
Settings that lets you choose which SIM card to use by default. Within a
given transport, Android prefers a network with the POLICY_TRANSPORT_PRIMARY
flag over a network without the flag.
A network agent uses the POLICY_EXITING
flag to identify a network that
is expected to disconnect. For example, Wi-Fi network quality degrades if a user
walks out of range of the network. Android avoids using a network with this flag
if another network without it's available. Each network agent can determine
when a network degrades enough to be considered exiting.
The NetworkScore
class also lets a network agent declare that Android keeps a
network connected using the KEEP_CONNECTED_FOR_HANDOVER
flag and the
NetworkScore.Builder.setKeepConnectedReason
method. This
KEEP_CONNECTED_FOR_HANDOVER
flag helps prospective networks. This flag lets a network
agent bring up a network on a secondary Wi-Fi STA without making it the primary
network until Android evaluates the network's performance. If a network agent
doesn't declare this flag, Android tears down prospective networks for not
servicing any request before the agent evaluates a network's performance.
If two networks can serve a given request and have equivalent policy, Android prefers the network that is serving the request. If no network is serving the request, Android chooses one of the two. This network continues to be preferred until policy flags change.
The network selection feature is implemented in the Connectivity module in
the Android Open Source Project (AOSP). The policy logic for network selection
is in the NetworkRanker
class and its helper classes. This means device
manufacturers can't directly customize the network selection code. Instead, they
must use the flags in NetworkScore
to convey information about networks.
Android 11
For devices running Android 11 or lower, Android performs network selection
based on an integer sent from a network agent (NetworkAgent
). 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 that the
network agent sends plus additional bonuses or penalties. Android applies these
bonuses or penalties based on conditions, for example, whether the network is
validated or a VPN. Network agents synchronize with each other to make policy
decisions.
If two networks can serve a given request and have the same numeric score, the behavior is undefined.
NetworkScore class
The NetworkScore
class is central to the network selection feature. This class
contains the API and documentation for the available flags and the
NetworkScore.Builder.setKeepConnectedReason
method.
You must build the NetworkScore
class using its builder class and pass it to
the NetworkAgent
constructor during initialization. You can update
network scores at any time using the NetworkAgent#sendNetworkScore
method.
Network agent implementation examples
AOSP includes example implementations of various network agents. The following list provides example implementations:
TelephonyNetworkAgent
: Uses network score to communicate policy for mobile networks.ClientModeImpl.WifiNetworkAgent
: Uses network score to communicate policy for Wi-Fi networks. This implementation provides backward compatibility with the legacy integer for network score by using thePOLICY_EXITING
flag.
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 changes using
NetworkScore
flags. The Connectivity Mainline module then uses the flags to
make network selection decisions. Device manufacturers using code for Android 11
or lower but building against the implementation in Android
12 can expect build errors because the methods for
updating the legacy integer were removed in Android 12.
For network agents that use the internal NetworkFactory
class, you must
express the score filter in a NetworkScore
object that represents 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 NetworkFactory
, unlike in Android 11
and lower, where it passes all requests.
You can pass a filter to simplify implementation and save battery, which ensures
that NetworkFactory
does not process all requests. However, if your custom
implementation requires that all requests be passed to NetworkFactory
, you can
register NetworkFactory.registerIgnoringScore
instead of the regular
NetworkFactory.register
method. If you use this method, pass a score
filter that most accurately represents the best score the factory can create.
This saves battery by preventing evaluation of requests that the factory can't
fulfill.
Validation
To verify network selection behavior on an Android-powered device, use the following tests:
NetworkScoreTest
CTS testNetworkRanker
unit test
Incorrect implementation might result in unexpected networks returning to apps
when they use NetworkCallback
. This includes selecting the device's
default network (the network the system sends to an app when it uses a network
callback, for example, with
ConnectivityManager.registerDefaultNetworkCallback
).
Another possible issue with incorrect implementation is severe battery drain. This occurs when a network agent is brought up with a score that doesn't let it qualify for any request and is torn down immediately after. If the agent repeatedly brings up and tears down, this can consume significant battery.