- Android – Connecting to WiFi programmatically
- Program flow
- How do I connect to a Wi-Fi network on Android programmatically using Kotlin?
- How to connect to Wifi network programatically on Android 10 and above?
- 1 Answer 1
- Connect to Wifi in Android Q programmatically
- 8 Answers 8
- Connect to a specific wifi programmatically in android using kotlin in android 10 and above
Android – Connecting to WiFi programmatically
We might have some scenarios , where application needs to connect the device to a WiFi access point. Application might have got the details of the Access point from other means like Bluetooth or image processing of the router image. Google showcased this feature using Google lens , where you point you camera at a wifi router and your device connects to the router
In this blog we will see how we can do this using kotlin as our programming language, we have already seen how to setup environment for kotlin development here.
The programs assumes that it already got the access point details to which it needs to connect.
Program flow
We have a simple activity with a button ,The real actions happens when we click the button
First the program checks if the device is already connected to requested AP, if yes it will simply shows a toast message
Then it will try to get the WiFiConfig the given ssid, if the WiFiConfig is not already present, it will create a new WiFiConfig for the ssid. So if a WiFiConfig is already present for a given ssid, it will not recreate it..if the passphrase is changed it might fail to connect, in your scenarios if it likely for the passphrase to change , then it is better to create the config on every time.
Once we got the WiFiConfig , we will disconnect from the present network, enable our WiFiConfig, then reconnect
We also have BroadCast Receiver which will show a toast message when the device is connected to the AP
We need to request for permissions and register to receive board casts
We have reused the layout from the previous example
The Config object has the details of AP
How do I connect to a Wi-Fi network on Android programmatically using Kotlin?
This example demonstrates how to connect to a Wi-Fi network on Android programmatically using Kotlin.
Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.
Step 2 − Add the following code to res/layout/activity_main.xml.
Step 3 − Add the following code to src/MainActivity.kt
import android.content.Context import android.net.wifi.WifiManager import android.os.Bundle import android.widget.Switch import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @Suppress("DEPRECATION") class MainActivity : AppCompatActivity() < private lateinit var wifiButton: Switch lateinit var textView: TextView lateinit var wifiManager: WifiManager override fun onCreate(savedInstanceState: Bundle?) < super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) title = "KotlinApp" textView = findViewById(R.id.textView) wifiButton = findViewById(R.id.switchWifi) wifiButton.setOnCheckedChangeListener < _, isChecked ->// TODO Auto-generated method stub if (isChecked) < textView.text = "WIFI ON" enableWiFi() >else < textView.text = "WIFI OFF" disableWiFi() >> > private fun disableWiFi() < wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager wifiManager.isWifiEnabled = false Toast.makeText(this, "Wifi Disabled", Toast.LENGTH_SHORT).show() >private fun enableWiFi() < wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager wifiManager.isWifiEnabled = true Toast.makeText(this, "Wifi Enabled", Toast.LENGTH_SHORT).show() >>
Step 4 − Add the following code to androidManifest.xml
Let’s try to run your application. I assume you have connected your actual Android Mobile device with your computer. To run the app from android studio, open one of your project’s activity files and click the Run icon from the toolbar. Select your mobile device as an option and then check your mobile device which will display your default screen.
Click here to download the project code.
How to connect to Wifi network programatically on Android 10 and above?
Used this code but it is not working on Android 10 and above.Also followed https://github.com/ThanosFisherman/WifiUtils but which also not working on Android 10 and above. Can some one suggest how to connect to wifi network.
1 Answer 1
You should try ConnectivityManager and NetworkCallbacks to do this task like this way:
@RequiresApi(Build.VERSION_CODES.Q) fun connectToWiFi(pin: String, ssid:String) < val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val specifier = WifiNetworkSpecifier.Builder() .setSsid(ssid) .setWpa2Passphrase(pin) .setSsidPattern(PatternMatcher(ssid, PatternMatcher.PATTERN_PREFIX)) .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .setNetworkSpecifier(specifier) .build() val networkCallback = object : NetworkCallback() < override fun onAvailable(network: Network) < super.onAvailable(network) showToast(context,context.getString(R.string.connection_success)) >override fun onUnavailable() < super.onUnavailable() showToast(context,context.getString(R.string.connection_fail)) >override fun onLost(network: Network) < super.onLost(network) showToast(context,context.getString(R.string.out_of_range)) >> connectivityManager.requestNetwork(request, networkCallback) >
Hi @Zahid Muneer thank you so much you made my day this code working perfectly. Can i know how to disconnect from the network once after connected.
private fun disconnectFromWiFi(network: Network) < val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager val wifiInfo = wifiManager.connectionInfo if (wifiInfo != null && wifiInfo.networkId == network.netId) < wifiManager.disableNetwork(wifiInfo.networkId) wifiManager.disconnect() >> you can try this function whenever you want to disconnect. Before calling this just save the network object in a variable that that we are receiving in onAvailable() method and pass it to this function as parameter.
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
Connect to a specific wifi programmatically in android using kotlin in android 10 and above
I want to connect to a specific wifi in android programmatically using kotlin. Till sdk level 28 we were using WifiManager api to connect to a specific wifi network programmatically, this is working fine for me. But from sdk level 29 this way is deprecated and new way of wifi connection is introduced which is Wi-Fi suggestion API to connect to a wifi with internet. But I am not able to figure out how to connect to specific wifi network using this new Wi-Fi suggestion API So please help me with it. This it the code which I am using to connect to a specific wifi.
private fun connect(ssid: String, password:String): Int < if (android.os.Build.VERSION.SDK_INT >= 29) < val suggestion1: WifiNetworkSuggestion = WifiNetworkSuggestion.Builder() .setSsid(ssid) .setWpa2Passphrase(password) .build() val suggestionsList: MutableList= ArrayList() suggestionsList.add(suggestion1) val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager val status = wifiManager.addNetworkSuggestions(suggestionsList) if (status == 0) < Toast.makeText(this, "PSK network added", Toast.LENGTH_LONG).show() // Log.i(TAG, "PSK network added: $status") >else < Toast.makeText(this, "PSK network not added", Toast.LENGTH_LONG).show() // Log.i(TAG, "PSK network not added: $status") >val specifier = WifiNetworkSpecifier.Builder() .setSsid(ssid) .setWpa2Passphrase(password) .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) .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.. println("on available"); >override fun onUnavailable() < // do failure processing here.. println("on unavailable"); >> connectivityManager.requestNetwork(request, networkCallback) return 123 > else < val networkSSID = ssid val networkPass = password val conf = WifiConfiguration() conf.SSID = "\"" + networkSSID + "\"" conf.wepKeys[0] = "\"" + networkPass + "\""; conf.wepTxKeyIndex = 0; conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40); conf.preSharedKey = "\""+ networkPass +"\""; val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager wifiManager.addNetwork(conf) var list = listOf() if (ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) < // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. >else < list = wifiManager.configuredNetworks >for (i in list) < if (i.SSID != null && i.SSID == "\"" + networkSSID + "\"") < wifiManager.disconnect() wifiManager.enableNetwork(i.networkId, true) wifiManager.reconnect() break >> return ssid.length > >
Have you tried the steps from here? stackoverflow.com/a/65327716/8407336 as your question is a duplicate of it