使用 WifiManager 打开 wifi 停止工作 Android 10
Turning on wifi using WifiManager stops to work on Android 10
我有以下代码,在 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 吗?
public boolean setWifiEnabled(布尔值启用)
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.
根据文档,Apps
将无法再从 Android-10 API level 29
[ 转向 Wi-Fi OFF/ON
,直到 google 提供替代解决方案].
有关详细信息,请参阅 official documentation。
issue 128554616 已在 google issuetracker
中创建了关于此的 issue 128554616。
我们知道上面提到的 google 问题跟踪器提到我们没有替代 api 已弃用的 setWiFiEnabled,我想我们需要寻找替代品,所以我使用 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable"));
或 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable"));
而 运行 测试在 API 29 或更高版本的设备上切换 WiFi。
您仍然可以在旧设备上使用旧的 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”已标记为已弃用,但仍可在旧设备上使用。
我不知道问题出在哪里,因为Google已经回答了:
If apps are targeting an older SDK ( Build.VERSION_CODES.P or below), they can continue to use this API.
因此将您的 Target SDK 更改为 28,它在 Android Q 上运行良好。
或者如果您需要通过 Tasker 或 Automate 等第二个应用程序更改 WiFi 状态:
- 安装Android工作室
- 创建一个新的项目名称 WiFiOn with Empty Activity and SDK 28
- 添加注释行:
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();
}
}
- 将minSdkVersion和targetSdkVersion改为28
build.grade(:app)
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.Whosebug.example"
minSdkVersion 28
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
- 向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"
...
使用 Android Studio 将其安装到您的 phone。
像 3. 一样创建一个新项目并将其命名为 WiFiOff 并在 MainActivity:
中更改行并重复所有步骤
...
wifi.setWifiEnabled(false); // true or false to activate/deactivate wifi
...
Toast toast = Toast.makeText(getApplicationContext(), "WiFi off",
...
我们可以在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
}
我有以下代码,在 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 吗?
public boolean setWifiEnabled(布尔值启用)
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.
根据文档,Apps
将无法再从 Android-10 API level 29
[ 转向 Wi-Fi OFF/ON
,直到 google 提供替代解决方案].
有关详细信息,请参阅 official documentation。
issue 128554616 已在 google issuetracker
中创建了关于此的 issue 128554616。
我们知道上面提到的 google 问题跟踪器提到我们没有替代 api 已弃用的 setWiFiEnabled,我想我们需要寻找替代品,所以我使用 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi enable"));
或 InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand("svc wifi disable"));
而 运行 测试在 API 29 或更高版本的设备上切换 WiFi。
您仍然可以在旧设备上使用旧的 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”已标记为已弃用,但仍可在旧设备上使用。
我不知道问题出在哪里,因为Google已经回答了:
If apps are targeting an older SDK ( Build.VERSION_CODES.P or below), they can continue to use this API.
因此将您的 Target SDK 更改为 28,它在 Android Q 上运行良好。
或者如果您需要通过 Tasker 或 Automate 等第二个应用程序更改 WiFi 状态:
- 安装Android工作室
- 创建一个新的项目名称 WiFiOn with Empty Activity and SDK 28
- 添加注释行:
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();
}
}
- 将minSdkVersion和targetSdkVersion改为28 build.grade(:app)
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.Whosebug.example"
minSdkVersion 28
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
- 向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"
...
使用 Android Studio 将其安装到您的 phone。
像 3. 一样创建一个新项目并将其命名为 WiFiOff 并在 MainActivity:
中更改行并重复所有步骤
...
wifi.setWifiEnabled(false); // true or false to activate/deactivate wifi
...
Toast toast = Toast.makeText(getApplicationContext(), "WiFi off",
...
我们可以在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
}