【问题标题】:Turning on wifi using WifiManager stops to work on Android 10使用 WifiManager 开启 wifi 停止在 Android 10 上工作
【发布时间】:2019-09-24 07:56:49
【问题描述】:

我有以下代码在 Android 10 之前运行良好。但它无法在 Android 10 设备中打开 wifi。

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 有什么变化吗?我应该做更多的事情来通过我的应用程序以编程方式打开 wifi 吗?

【问题讨论】:

    标签: android wifimanager android-10.0


    【解决方案1】:

    public boolean setWifiEnabled(启用布尔值)

    此方法在 API 级别 29 中已弃用。 从 Build.VERSION_CODES#Q 开始,不允许应用启用/禁用 Wi-Fi。

    兼容性说明:对于面向 Build.VERSION_CODES.Q 或更高版本的应用程序,此 API 将始终返回 false 并且无效。

    如果应用针对的是较旧的 SDK(Build.VERSION_CODES.P 或更低版本),它们可以继续使用此 API。

    根据文档,Apps 将无法再从 Android-10 API level 29 转换为 Wi-Fi OFF/ON[直到 google 提供替代解决方案]。

    有关更多信息,请参阅official documentation

    还有一个issue 128554616已经在google中创建了issuetracker

    【讨论】:

    • 非常感谢您提供的信息。能否请您说明一下用于打开 wifi 的替换 API?
    • 如何在 Android 10 上启用 wifi?试图理解你指向的文件。如果您可以在答案本身中暗示某些内容,那就太好了
    • 我在stackoverflow.com/questions/58075918/… 提出了一个后续问题。如果你也想回复那个。
    • 在 Android 10+ (SDK 29) 上根本无法以编程方式启用 wifi 吗?
    • 很好解释
    【解决方案2】:

    我不知道问题出在哪里,因为 Google 已经回答了:

    如果应用针对的是较旧的 SDK(Build.VERSION_CODES.P 或更低版本),它们可以继续使用此 API。

    因此,将您的 Target SDK 更改为 28,它在 Android Q 上运行良好。

    或者,如果您需要通过 Tasker 或 Automate 等第二个应用更改 WiFi 状态:

    1. 安装 Android Studio
    2. 使用 Empty ActivitySDK 28 创建一个名为 WiFiOn 的新项目
    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. minSdkVersiontargetSdkVersion 更改为 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",  
    ...
    

    【讨论】:

      【解决方案3】:

      您仍然可以在旧设备上使用旧 API(请参阅:official documentation),所以我就是这样做的:

      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”被标记为已弃用,但仍适用于旧设备。

      【讨论】:

      • 感谢您以不同的视角来回答这个问题
      【解决方案4】:

      由于我们知道上面提到的 google 问题跟踪器提到我们没有已弃用的 setWiFiEnabled 的替代 api,我想我们需要寻找替代方案,所以我在运行时使用 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable"));InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable"));测试以在 API 29 或更高版本的设备上切换 WiFi。

      【讨论】:

      • 这个怎么用?当我使用您的建议时,它不起作用。非常感谢。
      • 对于浓缩咖啡测试,我使用下面提到的方法。一个方法被创建为setWifiEnabled(),它看起来像:setWifiEnabled () { try { //Attempting toggling WiFi using WiFiManager } catch() { //Re-attempting toggling WiFi using svc shell command as mentioned above } } 这有帮助吗?如果没有,您能否提供有关您的用例的更多信息?
      • 那么这个只能用于测试吗?不适合最终用户?
      • 是的,我不会推荐任何这样的解决方法来为最终用户实现此功能,我们可以将我们的声音发送到issuetracker.google.com/issues/128554616,让 Google 知道我们需要这些 WiFi 切换 api/替代方案.
      【解决方案5】:

      我们可以在 Q 或更高版本中实用地启用禁用 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
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多