Включение Wi-Fi с помощью WifiManager перестает работать на Android 10

У меня есть следующий код, который хорошо работал до Android 10. Но он не может включить Wi-Fi на устройствах Android 10.

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

Ниже приведены мои разрешения в 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\"/>

Я даже динамически запрашиваю эти разрешения. Но, похоже, это тоже не помогает.

Вопрос:
Изменилось ли что-нибудь в Android 10? Должен ли я сделать что-то еще, чтобы программно включить Wi-Fi из моего приложения?


person AdeleGoldberg    schedule 24.09.2019    source источник


Ответы (4)


общедоступное логическое значение setWifiEnabled (логическое значение включено)

Этот метод устарел на уровне API 29. Начиная с Build.VERSION_CODES # Q, приложениям не разрешено включать / отключать Wi-Fi.

Примечание о совместимости: для приложений, предназначенных для Build.VERSION_CODES.Q или выше, этот API всегда будет возвращать false и не будет иметь никакого эффекта.

Если приложения нацелены на более старый SDK (Build.VERSION_CODES.P или ниже), они могут продолжать использовать этот API.

Согласно документации, Apps больше не сможет переключать Wi-Fi OFF/ON с Android-10 API level 29 [до тех пор, пока Google не предоставит альтернативное решение].

Для получения дополнительной информации см. официальную документацию.

И есть проблема 128554616, созданная в Google issuetracker по этому поводу.

person Jakir Hossain    schedule 24.09.2019
comment
Большое спасибо за информацию. Не могли бы вы также указать замену API, которая должна использоваться для включения Wi-Fi? - person AdeleGoldberg; 24.09.2019
comment
Как включить Wi-Fi на Android 10? Пытаюсь понять документ, на который вы указали. Было бы здорово, если бы вы могли что-то намекнуть в самом ответе - person AdeleGoldberg; 24.09.2019
comment
Я задал следующий вопрос на stackoverflow.com/questions/58075918/. Если вы хотите ответить и на этот вопрос. - person AdeleGoldberg; 24.09.2019
comment
Неужели вообще невозможно программно включить Wi-Fi на Android 10+ (SDK 29)? - person AdeleGoldberg; 24.09.2019
comment
Красиво объяснил - person Rahul Kushwaha; 25.09.2019

Вы по-прежнему можете использовать старый API на старых устройствах (см .: официальная документация), поэтому вот что я делаю:

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()
    }
}

WifiMgr.isWifiEnabled помечен как устаревший, но все еще работает на старых устройствах.

person Dave Enstrom    schedule 17.11.2020
comment
Спасибо, что ответили на этот вопрос с другой точки зрения. - person AdeleGoldberg; 17.11.2020

Поскольку мы знаем, что вышеупомянутый трекер проблем Google упоминает, что у нас нет заменяющего api для устаревшего setWiFiEnabled, я думаю, нам нужно искать альтернативы, поэтому я использую InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable")); или InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable")); при запуске тестов для переключения Wi-Fi на устройствах с API 29 или выше.

person Shredder    schedule 05.08.2020
comment
Как это использовать? Когда я использую ваше предложение, оно не работает. Большое тебе спасибо. - person henrichg; 23.08.2020
comment
Для тестов эспрессо я использую метод, описанный ниже. Метод создается как setWifiEnabled() и выглядит так: setWifiEnabled () { try { //Attempting toggling WiFi using WiFiManager } catch() { //Re-attempting toggling WiFi using svc shell command as mentioned above } } Это помогает? Если нет, не могли бы вы предоставить дополнительную информацию о вашем варианте использования? - person Shredder; 23.08.2020
comment
Тогда это можно использовать только для тестирования? Не для конечных пользователей? - person henrichg; 23.08.2020
comment
Да, я не буду рекомендовать какой-либо из таких обходных путей для реализации этого для конечных пользователей, и мы можем просто передать свой голос по адресу issueetracker.google.com/issues/128554616, чтобы сообщить Google, что нам нужны эти API / альтернативы с переключением Wi-Fi. - person Shredder; 23.08.2020

Я не знаю, в чем проблема, поскольку Google уже отвечает на нее:

Если приложения нацелены на более старый SDK (Build.VERSION_CODES.P или ниже), они могут продолжать использовать этот API.

Поэтому измените Target SDK на 28, и он отлично работает на Android Q.

Или, если вам нужно изменить состояние WiFi с помощью второго приложения, такого как Tasker или Automate:

  1. Установить Android Studio
  2. Создайте новое название проекта и WiFiOn с Пустым действием и SDK 28.
  3. Добавьте закомментированные строки:
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. Измените minSdkVersion и targetSdkVersion на 28 в 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. Добавить разрешение на 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. Используйте Android Studio, чтобы установить его на свой телефон.

  2. Создайте новый проект, как в 3., назовите его WiFiOff и повторите все шаги с измененными строками в MainActivity:

...
        wifi.setWifiEnabled(false); // true or false to activate/deactivate wifi
...
        Toast toast = Toast.makeText(getApplicationContext(), "WiFi off",  
...
person wlanrouter    schedule 26.11.2020