I'm currently trying to connect to a wifi network. I used the below code.
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setBssid(MacAddress.fromString(bssid))
.setWpa2Passphrase(password)
.build();
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(specifier)
.build();
ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
manager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
ConnectivityManager.setProcessDefaultNetwork(network);
super.onAvailable(network);
NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (info != null && info.isConnectedOrConnecting()) {
if (!emitter.isDisposed()) {
emitter.onSuccess(true);
}
} else {
if (!emitter.isDisposed()) {
emitter.onError(new RuntimeException("OS Disconnected"));
}
}
}
@Override
public void onUnavailable() {
super.onUnavailable();
if (!emitter.isDisposed()) {
emitter.onError(new RuntimeException("Could not connect Wifi"));
}
}
});
});
issue: the above code works well with Pixel phone and Nokia but on Oneplus devices, I get toast connection success toast and immediately after this wifi gets disconnected. wifi Symbol is visible very briefly in the status bar. In the next Moment, Wifi-Symbol is gone and the system Dialog is visible again, to connect to the wifi.
Have given below the permissions, and location permission is granted and it is enabled in the device also.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
When I debug the Callback it is going through the methods in this Order:
I have already referred these
Android Q, programmatically connect to different WiFi AP for internet
WiFi Network Connection keeps disconnecting on Android Q
Wifi Network Request Api connection issue in android 10 (Q)
Android Q, WifiNetworkSpecifier loosing Wifi immediately after connection is established
and I could not able to find a solution.
Is there anything I'm missing in network request that causes disconnection. or any other solution appreciated.
Thank you.
This issue still doesn't seem to be fixed as of September 2020 on certain devices, Oneplus 6, Nokia phones etc seem to be exhibiting this success connection loop. In the meantime if you have a iOT device your app is trying to auto connect and it fails you can try this in the onFail(), to dismiss the connection dialog and take your users gracefully to the wifi page to manually connect.
connectivityManager.bindProcessToNetwork(null);
connectivityManager.unregisterNetworkCallback(networkCallback);
AlertDialog.Builder alert = new AlertDialog.Builder(...);
alert.setTitle(...);
alert.setMessage(...);
alert.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
alert.show();
}
Late to the conversation but, have you tried calling connectivityManager.bindProcessToNetwork(network)
whenever you find an available network?
Here's an example of what I mean based on your question's code:
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setBssid(MacAddress.fromString(bssid))
.setWpa2Passphrase(password)
.build();
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(specifier)
.build();
ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
manager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
// This is the new line of code
ConnectivityManager.bindProcessToNetwork(network);
NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (info != null && info.isConnectedOrConnecting()) {
if (!emitter.isDisposed()) {
emitter.onSuccess(true);
}
} else {
if (!emitter.isDisposed()) {
emitter.onError(new RuntimeException("OS Disconnected"));
}
}
}
...
}
If you are trying to connect to a network that does not provide access to the internet, instead of
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(specifier)
.build();
try
NetworkRequest request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build()
Apparently, internet capability is required by default.
The documentation (see https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder#build()) says
Create a specifier object used to request a local Wi-Fi network. The generated NetworkSpecifier should be used in NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier) when building the NetworkRequest. These specifiers can only be used to request a local wifi network (i.e no internet capability). So, the device will not switch it's default route to wifi if there are other transports (cellular for example) available.
I don't really understand this paragraph, but it talks about the device switching back to the default route, what would cause a disconnection from your target network.
The example that is provided there includes the line
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
I copied the example and it worked for me. Never tried to make the connection without the line above.
However, I only had tried to connect to a network with internet connection. To my surprise, when I tried to connect to one without it, in spite of the documentation, the connection fails.
I have been tracking & researching this a lot. All my findings along with my current most optimal solution can be found here
But more specific to your question is the following info taken from the link
As stated here by Google, some OEM Roms are not 'holding on to the request' and therefore the connection is dropping instantly. OnePlus have fixed this problem in some of their later models but not all. This bug will continuously exist for certain phone models on certain Android builds, therefore a successful fallback (i.e. a manual connection with no network disruption) is required. No known workaround is available
removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) wont help keep the connection on a OnePlus as stated here
setting the Bssid wont help keep the connection on a OnePlus as stated here
google cannot help, they have stated it is out of their hands here
OnePlus forum posts confirming it working for some models (but not all) after an update, see here, here & here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With