7

I have following code which used to work well pre Android 10. But it is not able to turn wifi on in Android 10 devices.

WifiManager wifiMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
boolean res = wifiMgr.setWifiEnabled(true);
//res value is set to false above because setWifiEnabled returns false on Android 10

Following are my permissions in AndroidManifest.xml

<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>
<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>
<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>
<uses-permission android:name=\"android.permission.INTERNET\"/>
<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>

I am even dynamically requesting for these permissions. But that doesn't seem to help as well.

Question:
Has anything changed on Android 10? Should I do something more to turn on wifi programatically from my app?

AdeleGoldberg
  • 1,289
  • 3
  • 12
  • 28

5 Answers5

8

public boolean setWifiEnabled (boolean enabled)

This method was deprecated in API level 29. Starting with Build.VERSION_CODES#Q, applications are not allowed to enable/disable Wi-Fi.

Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always return false and will have no effect.

If apps are targeting an older SDK ( Build.VERSION_CODES.P or below), they can continue to use this API.

According to documentation, Apps will not be able to turn Wi-Fi OFF/ON anymore from Android-10 API level 29[Until google provides an alternative solution].

For more information see official documentation.

And there is an issue 128554616 has been created in google issuetracker about this.

Jakir Hossain
  • 3,830
  • 1
  • 15
  • 29
4

You can still use the old API on older devices (see: official documentation), so here is what I do:

val wifiMgr = this.applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
val alertDial: AlertDialog.Builder = AlertDialog.Builder(this)

//
//=============== Start Wi-Fi if needed ====================
//     Check Wi-Fi state: 1=disabled WIFI_STATE_DISABLED
if (wifiMgr.wifiState == 1) {
    alertDial.setMessage(R.string.wifi)
        .setCancelable(false)
        .setPositiveButton(R.string.yes) { _, _ ->  // Enable wifi
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
                startActivityForResult(panelIntent, 0)
            } else {
                wifiMgr.isWifiEnabled = true
            }
        }
        .setNegativeButton(R.string.no) { _, _ ->   // Disable wifi
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
                startActivityForResult(panelIntent, 0)
            } else {
                wifiMgr.isWifiEnabled = false
            }
        }
    alertDial.show()
    }
}

The "wifiMgr.isWifiEnabled" is marked as deprecated, but still works on older devices.

Dave Enstrom
  • 105
  • 7
1

As we are aware that the above mentioned google issue tracker mentions that we do not have a replacement api for the deprecated setWiFiEnabled, I guess we need to look out for alternatives and so I use InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable")); or InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable")); while running tests to toggle WiFi on devices with API 29 or above.

Shredder
  • 150
  • 1
  • 1
  • 15
  • How to use this? When I use your suggestion, it not working. Thank you very much. – henrichg Aug 23 '20 at 13:12
  • For espresso tests, I use the method like mentioned below. A method is created as `setWifiEnabled()` and it looks like: `setWifiEnabled () { try { //Attempting toggling WiFi using WiFiManager } catch() { //Re-attempting toggling WiFi using svc shell command as mentioned above } }` Does that help? If not, can you please provide some more info about your use case? – Shredder Aug 23 '20 at 14:29
  • Then this can be used only for testing? Is not for end users? – henrichg Aug 23 '20 at 14:55
  • Yes, I won't recommend any of such workaround for implementing this for end users and we can just cast our voice at https://issuetracker.google.com/issues/128554616 for letting Google know that we need these WiFi toggling apis / alternatives back. – Shredder Aug 23 '20 at 15:24
1

I don't know where the problem is, as Google is answering it already:

If apps are targeting an older SDK ( Build.VERSION_CODES.P or below), they can continue to use this API.

So change your Target SDK to 28 and it works fine on Android Q.

Or if you need to change WiFi State by second Apps like Tasker or Automate:

  1. Install Android Studio
  2. Create a new Project namend WiFiOn with Empty Activity and SDK 28
  3. Add commented lines:
import androidx.appcompat.app.AppCompatActivity;

import android.net.wifi.WifiManager;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Add WiFi On Part
        WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        wifi.setWifiEnabled(true); // true or false to activate/deactivate wifi


        // Add Toast if you want to
        Toast toast = Toast.makeText(getApplicationContext(), "WiFi on",  Toast.LENGTH_SHORT);
        toast.show();

        // Add Close Activity immediatelly
        finish();

    }
}
  1. Change minSdkVersion and targetSdkVersion to 28 in build.grade(:app)
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.stackoverflow.example"
        minSdkVersion 28
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
  1. Add Permission to AndroidMAnifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.p1apps.wifion">
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <application
        android:allowBackup="true"
...
  1. Use Android Studio to install it on your phone.

  2. Create a new Project like in 3. and name it WiFiOff and repeat all steps with changed lines in MainActivity:

...
        wifi.setWifiEnabled(false); // true or false to activate/deactivate wifi
...
        Toast toast = Toast.makeText(getApplicationContext(), "WiFi off",  
...
wlanrouter
  • 39
  • 2
0

We can enable disable wifi pragmatically in version Q or above

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
    startActivityForResult(panelIntent, 0)
} else {
    wifiMgr.isWifiEnabled = true
} 
ZygD
  • 22,092
  • 39
  • 79
  • 102