4

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.stack.imgur.com/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.

Avijit Das
  • 43
  • 1
  • 8

2 Answers2

2

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)
    }
} 
Siddharth Kamaria
  • 2,448
  • 2
  • 17
  • 37
  • That does not sounds like a legitimate ask to the client/customer. If I see the setting app, it is able to switch between WiFi networks without any other human intervention. If you have any experience on production software, please suggest. – Avijit Das Sep 09 '20 at 10:09
  • @AvijitDas For API 29+, `Settings.Panel.ACTION_WIFI` will show you the Wi-Fi selection without taking up your entire screen. IMHO, it is still better than letting the call to `setWifiEnabled(true)` do nothing for you! Hence, the if-else block in the code :) – Siddharth Kamaria Sep 09 '20 at 10:26
  • 1
    Thank you for your suggestion, let me try that. – Avijit Das Sep 09 '20 at 10:45
  • Thank you Siddharth, This may solve the purpose :) Is there a way to prevent the notification ? – Avijit Das Sep 11 '20 at 09:26
  • @AvijitDas Are you referring to the `setWifiEnabled(true)` warning notification? If yes, then I'm not aware of any way to disable it. – Siddharth Kamaria Sep 11 '20 at 10:28
1

Note: This method only works as long as you don't target Android Q (API 29) and above.

and no there is no way to automate the enabling process.

To Enable

    public void EnableWiFi(){
      wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
      wifiManager.setWifiEnabled(true);
   }

To Disable

 public void DisableWiFi(){
      wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
      wifiManager.setWifiEnabled(false);
   }
Ali
  • 519
  • 4
  • 13
  • Thanks Ali for quick response. I am trying it on API 30. Is there any way to achieve what I am trying on API 30. I checked setWifiEnabled is deprecated since API 29. – Avijit Das Sep 08 '20 at 12:45
  • 1
    Yes exactly **it has been deprecated** – Ali Sep 08 '20 at 12:46
  • I dont think there is any workaround, but you can do it in below API 30 and the manual functionality for API 30 – Ali Sep 08 '20 at 12:47
  • Sure, I can try it. Thank you again. – Avijit Das Sep 08 '20 at 12:51
  • this code worked on API 28 and bellow. I would still like to have a solution on 29 and above. – Avijit Das Sep 09 '20 at 10:12
  • This specific action is android version dependent, So you might not have any solution except for this on. please notice you cannot achieve this behaviour on 29+. – Ali Sep 09 '20 at 11:18
  • Setting app in Android is doing the same thing. May be it is running with System permission. I can give it a try. – Avijit Das Sep 10 '20 at 06:46