Search code examples
androidkotlinandroid-wifi

Connecting to a specific wifi network programmatically in Android (API 30)


Purpose Try to connect or switch to a specific WiFi network without any human intervention (other than username and password).

Code Snippet

MainActivity.kt

class MainActivity : AppCompatActivity() {

private var lastSuggestedNetwork:WifiNetworkSuggestion? = null
var wifiManager:WifiManager? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
    val button = findViewById<Button>(R.id.button) // Just a button in the layout file
    button.setOnClickListener(View.OnClickListener {
        wifiManager!!.disconnect()
        connectUsingNetworkSuggestion(ssid = "AndroidWifi", password ="")
        wifiManager!!.reconnect()
    })
}

private fun connectUsingNetworkSuggestion(ssid: String, password: String) {
    val wifiNetworkSuggestion = WifiNetworkSuggestion.Builder()
        .setSsid(ssid)
        .setWpa2Passphrase(password)
        .build()
    val intentFilter =
        IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

    val broadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                return
            }
            showToast("Connection Suggestion Succeeded")
        }
    }


    registerReceiver(broadcastReceiver, intentFilter)

    lastSuggestedNetwork?.let {
        val status = wifiManager!!.removeNetworkSuggestions(listOf(it))
        Log.i("WifiNetworkSuggestion", "Removing Network suggestions status is $status")
    }
    val suggestionsList = listOf(wifiNetworkSuggestion)

    var status = wifiManager!!.addNetworkSuggestions(suggestionsList)
    Log.i("WifiNetworkSuggestion", "Adding Network suggestions status is $status")
    if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE) {
        showToast("Suggestion Update Needed")
        status = wifiManager!!.removeNetworkSuggestions(suggestionsList)
        Log.i("WifiNetworkSuggestion", "Removing Network suggestions status is $status")
        status = wifiManager!!.addNetworkSuggestions(suggestionsList)
    }
    if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
        lastSuggestedNetwork = wifiNetworkSuggestion
        showToast("Suggestion Added")
    }
}

private fun showToast(s: String) {
    Toast.makeText(applicationContext, s, Toast.LENGTH_LONG).show()
}

}

AndroidManifest.xml permission

 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

With this code, the device is able to connect to the WiFi network but for that the WiFi needs to be turned off and on manually. There must be a better way to connect or switch to a specific WiFi network without any manual operation.

Current process:

  1. Run the application and click on button on the home screen to connect to WiFi.
  2. Go to settings, disable and enable to WiFi
  3. Device is connect to the desired WiFi network

Output https://i.sstatic.net/zQ7Bo.png

Intention: Get rid of step#2/ Do it programmatically

Reference: Ref: Is it possible to add a network configuration on Android Q?

Just to make it clear, the ssid and password mentioned in this code snippet is for default AVD, Just change it to any other WiFi network's SSID and password, it works on physical devices. I tried it on Pixel 3XL with the same problem.


Solution

  • You can use gently ask your users to turn on the wifi by using the new Settings.Panel (API 29+) or the old Settings API. Additionally, you can use startActivityForResult() to check if the user did turn on the Wifi from the Settings.

    if(!wifiManager.isWifiEnabled()) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startActivity(new Intent(Settings.Panel.ACTION_WIFI));
        } else {
            // Use a full page activity - if Wifi is critcal for your app
            startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
            // Or use the deprecated method
            wifiManager.setWifiEnabled(true)
        }
    }