On Android 10 (API level 29) and higher devices, you can use a new peer to peer API to
bootstrap configuration for secondary devices like Chromecast and Google Home
hardware. This feature enables your app to prompt the user to change the access
point that the device is connected to by using
WifiNetworkSpecifier
to describe properties of a requested network.
To use this API, do the following:
Create a Wi-Fi network specifier using
WifiNetworkSpecifier.Builder
.Set a network filter to match networks to connect to, along with required credentials.
Decide on a combination of
SSID
,SSID pattern
,BSSID
, andBSSID pattern
to set the network filter in each request, subject to the following requirements:- Each request should provide at least one of
SSID
,SSID pattern
,BSSID
, orBSSID pattern
- Each request can set only one of
SSID
orSSID pattern
- Each request can set only one of
BSSID
orBSSID pattern
- Each request should provide at least one of
Add the specifiers to the network request along with a
NetworkCallback
instance to track the status of the request.If the user accepts the request and the connection to the network is successful,
NetworkCallback.onAvailable()
is invoked on the callback object. If the user denies the request or if the connection to the network is unsuccessful,NetworkCallback.onUnavailable()
is invoked on the callback object.
Initiating the request to connect to a peer device launches a dialog box on the same device, from which that device's user can accept the connection request.
Bypassing user approval
Once the user approves a network to connect to in response to a request from a specific app, the device stores the approval for the particular access point. If the app makes a specific request to connect to that access point again, the device skips the user approval phase and automatically connects to the network. If the user chooses to forget the network while connected to a network requested by the API, then this stored approval for that combination of app and network is removed, and any future request from the app must be approved by the user again. If the app makes a non-specific request, such as with an SSID or BSSID pattern, then the user must approve the request.
Code sample
The following code sample shows how to connect to an open network with an SSID
prefix of "test"
and a BSSID OUI of "10:03:23"
:
Kotlin
val specifier = WifiNetworkSpecifier.Builder() .setSsidPattern(PatternMatcher("test", PatternMatcher.PATTERN_PREFIX)) .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00")) .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier) .build() val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkCallback = object : ConnectivityManager.NetworkCallback() { ... override fun onAvailable(network: Network?) { // do success processing here.. } override fun onUnavailable() { // do failure processing here.. } ... } connectivityManager.requestNetwork(request, networkCallback) ... // Release the request when done. connectivityManager.unregisterNetworkCallback(networkCallback)
Java
final NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder() .setSsidPattern(new PatternMatcher("test", PatternMatcher.PATTERN_PREFIX)) .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"), MacAddress.fromString("ff:ff:ff:00:00:00")) .build(); final NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier) .build(); final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkCallback networkCallback = new NetworkCallback() { ... @Override void onAvailable(...) { // do success processing here.. } @Override void onUnavailable(...) { // do failure processing here.. } ... }; connectivityManager.requestNetwork(request, networkCallback); ... // Release the request when done. connectivityManager.unregisterNetworkCallback(networkCallback);