Connect to wifi device android

Connect to Wifi in Android Q programmatically

I had this function to connect in Wifi network, below Android 10 it works fine, but when I tried on Android 10, I had a successful connection but WITHOUT internet, I knew it’s a bug in Android 10 but I found this application which can connect to wifi from Android 10 with no problem. I’m blocked for days. My function :

private void connectToWifi(String ssid, String password) < WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) < try < Log.e(TAG,"connection wifi pre Q"); WifiConfiguration wifiConfig = new WifiConfiguration(); wifiConfig.SSID = "\"" + ssid + "\""; wifiConfig.preSharedKey = "\"" + password + "\""; int netId = wifiManager.addNetwork(wifiConfig); wifiManager.disconnect(); wifiManager.enableNetwork(netId, true); wifiManager.reconnect(); >catch ( Exception e) < e.printStackTrace(); >> else < Log.e(TAG,"connection wifi Q"); WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder() .setSsid( ssid ) .setWpa2Passphrase(password) .build(); NetworkRequest networkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .setNetworkSpecifier(wifiNetworkSpecifier) .build(); connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); networkCallback = new ConnectivityManager.NetworkCallback() < @Override public void onAvailable(Network network) < super.onAvailable(network); connectivityManager.bindProcessToNetwork(network); Log.e(TAG,"onAvailable"); >@Override public void onLosing(@NonNull Network network, int maxMsToLive) < super.onLosing(network, maxMsToLive); Log.e(TAG,"onLosing"); >@Override public void onLost(Network network) < super.onLost(network); Log.e(TAG, "losing active connection"); >@Override public void onUnavailable() < super.onUnavailable(); Log.e(TAG,"onUnavailable"); >>; connectivityManager.requestNetwork(networkRequest,networkCallback); > > 

@euphor but that won’t work after 2nd Nov deadline. We can’t push update to play store after 2nd Nov. Any other workaround?

8 Answers 8

So far what is working for me on the majority of devices I have tested with, with a fallback option to at least stop the dreaded ‘looping request’ and to allow a successful manual connection

The below code is written in Kotlin, please google how to covert to Java if needed.

Create a NetworkCallback which is required for API >= 29 (prior it was not required but could be used)

val networkCallback = object : ConnectivityManager.NetworkCallback() < override fun onAvailable(network: Network) < super.onAvailable(network) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) < // To make sure that requests don't go over mobile data connectivityManager.bindProcessToNetwork(network) >else < connectivityManager.setProcessDefaultNetwork(network) >> override fun onLost(network: Network) < super.onLost(network) // This is to stop the looping request for OnePlus & Xiaomi models connectivityManager.bindProcessToNetwork(null) connectivityManager.unregisterNetworkCallback(networkCallback) // Here you can have a fallback option to show a 'Please connect manually' page with an Intent to the Wifi settings >> 

Connect to a network as follows:

val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder() .setSsid(ssid) .setWpa2Passphrase(pass) .build() val networkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // Add the below 2 lines if the network should have internet capabilities. // Adding/removing other capabilities has made no known difference so far // .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) // .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .setNetworkSpecifier(wifiNetworkSpecifier) .build() connectivityManager.requestNetwork(networkRequest, networkCallback) 

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, but if found I will update it here as an option.

To remove the network, do the following:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) < //This is required for Xiaomi models for disconnecting connectivityManager.bindProcessToNetwork(null) >else < connectivityManager.setProcessDefaultNetwork(null) >connectivityManager.unregisterNetworkCallback(it) 

Please keep in mind, an automatic connection allows for an automatic & manual disconnection. A manual connection (such as the suggested fallback for OnePlus devices) does not allow an automatic disconnection. This will also need to be handled within the app for a better UX design when it comes to IoT devices.

Читайте также:  Вай фай интернет алкатель

Some extra small tips & info:

  • now that a system dialog opens, the app calls onPause and onResume respectively. This affected my logic regarding automatic connection to IoT devices. In some case, onResume is called before the network callback is finished.
  • In regards to tests, I have yet to be able to get around the dialog by just using espresso and it may block some tests that were working before API 29. It may be possible using other frameworks such as uiautomator. In my case I adjusted the tests to work up until the dialog shows, and run further tests thereafter. Using Intents.init() does not work.
  • onUnavailable is called when the the network has been found, but the user cancels. It is not called when the network was not found or if the user cancels the dialog before the network has been found, in this case no other methods are called, use onResume to catch it.
  • when it fails on the OnePlus it called onAvailable() -> onCapabilitiesChanged() -> onBlockedStatusChanged (blocked: false) -> onCapabilitiesChanged() -> onLost() respectively
  • 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
  • when GPS is switched off, the SSID names of networks are not available
  • if the dialog comes several times, check your own activity lifecycle, in my case some models were calling onResume before the network callback was received.
  • manually connecting to a network without internet capabilities needs user confirmation to keep the connection (sometimes in the form of a dialog or as a notification), if ignored, the system will disconnect from the network shortly afterwards
  • Google Pixel 2 — No issues found
  • Samsung S10 SM-G970F — No issues found
  • Samsung S9 SM-G960F — No issues found
  • One Plus A5000 (OxegenOS 10.0.1) — Major Issue with automatic connection
  • HTC One M8 (LineageOS 17.1) — No issues found
  • Xiaomi Mi Note 10 — Issue with disconnecting (Fixed, see code example)
  • Samsung A50 — Dialog repetitively appears after successful connection (sometimes)
  • Huawei Mate Pro 20 — Dialog repetitively appears after successful connection (sometimes)
  • Huawei P40 Lite — Doesn’t call onLost()
  • CAT S62 Pro — No issues found
  • Sony Xperia SZ2 — No issues found
  • Samsung Note10 — No issues found
Читайте также:  Одновременно две wi fi сети

Источник

Cheesy bits and bobs

A blog about cross-platform mobile app development and other programming related things. Written by Mastodon.

Microsoft MVP

Planet Xamarin Featured Blog

Xamarin Certified Mobile Developer

Connecting to WiFi in Android 10

Android 10 was recently released and it introduces a bunch of changes in terms of Privacy. This means that access to /proc/net from the Linux sub-system has been restricted, which requires you to use NetworkStatsManager and ConnectivityManager to get VPN information.

It adds restrictions to who is allowed to enable/disable WiFi. We could previously use WifiManager.SetWifiEnabled() , but not anymore, this method will return false . You will need to show one of the new Settings Panels, which shows a slice of the Android Settings within your App.

What this post will focus on is the restrictions to access to configured networks and connecting to networks. A bunch of the network API has changed, so let us look a bit into what we have available now.

Suggesting networks

Something new to Android 10 is suggesting networks to connect to. These are just hints to the platform that the networks you provide it, can be connected to and it might decide to chose one of them. When any of these networks are detected nearby, Android will show a notification to the user the first time, which is how they allow connecting to a suggested network.

This could be useful for an Enterprise App, which can allow Access to networks depending on the logged in user or suggest a separate network for guests.

You can suggest networks like so.

var guestUsers = new WifiNetworkSuggestion.Builder() .SetSsid("GuestNetwork") .SetWpa2Passphrase("hunter2") .Build(); var secretEnterpriseNetwork = new WifiNetworkSuggestion.Builder() .SetSsid("Cyberdyne") .SetWpa2Passphrase(":D/-) .Build(); var suggestions = new[]  guestUsers, secretEnterpriseNetwork >; var wifiManager = this.GetSystemService(Context.WifiService) as WifiManager; var status = wifiManager.AddNetworkSuggestions(suggestions); if (status == NetworkStatus.SuggestionsSuccess)  // We added suggestions! > 

The suggestions you provide can only be added once. If you try add the same suggestion again, the status from AddNetworkSuggestion will return SuggestionsErrorAddDuplicate . If you need to modify a suggestion, you need to remove it first with RemoveNetworkSuggestion , then add the modified version of it again. Additionally, in order to add these suggestions you will need to add the CHANGE_WIFI_STATE permission to your AndroidManifest.xml.

 android:name="android.permission.CHANGE_WIFI_STATE" /> 

Note: Some of the options on a WifiNetworkSuggestion requires you to request Fine Location permission in order to work. Make sure to consult the Android documentation to be sure.

After you run AddNetworkSuggestion don’t expect something to happen immediately. There will eventually be a notification in the notification drawer. Which looks like something in the image below. Choosing “Yes” on the notification, won’t necessarily automatically connect to the network. However, going to Wifi Settings on your device, it should now know how to connect to that network.

suggestion notificationsuggestion wifi settings

Connecting to Specific Networks

Prior to Android 10, we could explicitly tell Android to connect to a specific Network and it would simply do it. This was done using WifiManager.AddNetwork() where you provided a WifiConfiguration . Now this API has been deprecated and replaced with ConnectivityManager.RequestNetwork , where you build a Network Request with a Wifi Specification, similar to the suggestions I showed you above. However, it also allows you to specify, whether the connection requires Internet, cannot be VPN, has to be WiFi and more.

You will also need to provide a ConnectivityManager.NetworkCallback , which will let you know whether connection to the network was successful or not. The idea here is that you are awaiting the requested network to connect and only when that is successful you can continue with your execution.

This is excellent for scenarios, where you need to be on a specific network to do some specific operations. One thing to note is that you will only be able to connect to this network while the App is open. As soon as the App is closed, it disconnects the network.

Note: this connection will not have any Internet connectivity according to the Google docs. See the notes in the Android documentation about WiFi Bootstrapping. For Internet connectivity Google suggests to use the Network Suggestions described above.

var specifier = new WifiNetworkSpecifier.Builder() .SetSsid("cyberdyne") .SetWpa2Passphrase("ill be back") .Build(); var request = new NetworkRequest.Builder() .AddTransportType(TransportType.Wifi) // we want WiFi .RemoveCapability(NetCapability.Internet) // Internet not required .SetNetworkSpecifier(specifier) // we want _our_ network .Build(); var connectivityManager = this.GetSystemService(Context.ConnectivityService) as ConnectivityManager; connectivityManager.RequestNetwork(request, callback); 

Here is an example of wanting to connect to the network with SSID “cyberdyne” and passphrase “ill be back”. The transport type specifies what kind of network you want to connect to. In this case it is a WiFi network. We do not require any Internet capability on the network. Per default it requests Internet, Not VPN and Trusted capabilities.

The callback looks something like this.

private class NetworkCallback : ConnectivityManager.NetworkCallback  public ActionNetwork> NetworkAvailable  get; set; > public override void OnAvailable(Network network)  base.OnAvailable(network); NetworkAvailable?.Invoke(network); > > var callback = new NetworkCallback  NetworkAvailable = network =>  // we are connected! > >; 

You can also use OnUnavailable to detect that we could not connect to the network in particular, or the user pressed cancel.

Connect to Device Request

If you connect once to a network request, any subsequent requests will automatically connect if you are in range of the network and the user will not have accept it again. Also, while the App is open and you want to disconnect from the requested network, you simply call ConnectivityManager.UnregisterNetworkCallback() on the callback.

This hopefully gives you an idea about how to connect to WiFi Networks with Android 10.

You can check out the code from my Android 10 WiFi Repository on GitHub and have a go at playing with it yourself.

Источник

Оцените статью
Adblock
detector