使用 WifiManager 打开 wifi 在 Android 10 上停止工作

问题描述 投票:0回答:6

我有以下代码,在 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
6个回答
8
投票

public boolean 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提供替代解决方案]。

更多信息请参阅官方文档

并且在谷歌issuetracker中已经创建了一个关于此问题的

问题128554616


4
投票

您仍然可以在旧设备上使用旧的 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”被标记为已弃用,但仍适用于较旧的设备。


1
投票

正如我们所知,上述谷歌问题跟踪器提到我们没有已弃用的 setWiFiEnabled 的替代 API,我想我们需要寻找替代方案,因此我在运行测试时使用

InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable"));
InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable"));
在 API 29 或更高版本的设备上切换 WiFi。


1
投票

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

如果应用程序面向较旧的 SDK(Build.VERSION_CODES.P 或更低版本),则可以继续使用此 API。

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

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

  1. 安装Android Studio
  2. 使用 Empty ActivitySDK 28 创建一个名为 WiFiOn
  3. 的新项目
  4. 添加注释行:
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",  
...

0
投票

我们可以在 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
} 

0
投票

我发现 WiFiManager.disableNetwork() 可以完成这项工作:

LWifiConf := TJWifiConfiguration.Wrap( List.get(i) );
LSsid := JStringToString( LWifiConf.SSID );
LNetId := LWifiConf.networkId;

Resb:= WiFiManager.disableNetwork(LNetId);
Memo1.Lines.Add('disableNetwork action: ' + Resb.ToString);

它会断开连接并且不会重新连接,至少在 wifi 循环关闭之前是这样。 在 Android 版本 6.0 和 SDK_INT 25 上进行测试

要重新连接,我们可以通过编程再次执行。

© www.soinside.com 2019 - 2024. All rights reserved.