AndroidQ及以上如何实现WiFi切换
背景
从Android Q开始,原WiFi操作API部分被废弃,eg: enableNetwork、getConfiguredNetworks等。取而代之的是WifiNetworkSpecifier,WifiNetworkSuggestion等新API(主要从安全和用户体验的角度出发,废弃了之前太过底层的API)。
新版API简介(可跳过)
- WifiNetworkSpecifier:此API的目的是允许Android设备之间建立点对点连接,比如用APP连接一个新的设备,通过APP给设备做配置(因为很多设备没有操作界面)。(非网络目的,实测当通过此API连接上WiFi后,除了APP本身以外其他APP均无法连接互联网,代码放在这,大家可以测一下)
private void connWifi(String ssid, String password) {
WifiNetworkSpecifier.Builder builder = null;
if (SDK_INT >= android.os.Build.VERSION_CODES.Q) {
builder = new WifiNetworkSpecifier.Builder();
builder.setSsid(ssid);
builder.setWpa2Passphrase(password);
WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
networkRequestBuilder.setNetworkSpecifier(wifiNetworkSpecifier);
NetworkRequest networkRequest = networkRequestBuilder.build();
ConnectivityManager cm = (ConnectivityManager)
getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager.NetworkCallback networkCallback = new
ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
cm.bindProcessToNetwork(network);
}
};
cm.requestNetwork(networkRequest, networkCallback);
}
}
- WifiNetworkSuggestion:网络建议API,你可以给用户提供多个WIFI凭据作为网络建议,但系统不一定会用你给的这个WIFI,因为可能已经连接了一个其他的WIFI。(所以说是建议,不是强制修改)
private void addSuggesstionWiFi(String ssid, String password) {
final WifiNetworkSuggestion guest;
if (SDK_INT >= android.os.Build.VERSION_CODES.Q) {
guest = new WifiNetworkSuggestion.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.setIsAppInteractionRequired(false) // Optional (Needs location permission)
.build();
final List<WifiNetworkSuggestion> suggestionsList = new ArrayList<>();
suggestionsList.add(guest);
final WifiManager wifiManager =
(WifiManager) NetWorkActivity.this.getSystemService(Context.WIFI_SERVICE);
final int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
toast("添加" + ssid + "到建议列表失败!");
return;
}
}
}
AndroidQ及以上如何实现WiFi切换(重点)
从上面的内容来看,新版的API没有给我们提供实现WiFi切换的功能,所以在新版API上的努力都是白费(后面会不会支持不知道)。我们要实现WiFi切换只能从老的API入手。而老的API是否可以运行主要取决于我们的编译版本和目标SDK。所以只要在gradle做如下配置:
android {
compileSdkVersion 28
......
defaultConfig {
......
targetSdk 28
}
}
- compileSdkVersion: 编译版本决定了你可以使用哪些API,比如你指定compileSdkVersion=16,你就不能使用compileSdkVersion=17中的API。
- targetSdk:只是告诉系统你在哪个版本上测试通过了,与应用程序的编译方式或您可以使用的API无关,系统会保证哪怕在高版本的SDK运行环境下,你所用API的行为也会和targetSdk所指定的版本运行行为保持一致。(说的通俗点就是系统会向前兼容老版本的API)
最后写一下怎么实现:
private void switch2Wifi(String ssid) {
WifiConfiguration wifiConfigure = getWiFiConfigure(ssid);
if (wifiConfigure != null) {
boolean enabled = wifiManager.enableNetwork(wifiConfigure.networkId, true);
if (enabled) {
//注意,这里虽然enbale了,但是WiFi可能还没哟启动好,所以要手动判断下
//todo 监听网络是否准备好,这里比较挫,后面优化
while (!wifiManager.isWifiEnabled()) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} else {
toast("请先连接WiFi:" + ssid);
}
}
private WifiConfiguration getWiFiConfigure(String SSID) {
if (wifiManager != null) {
List<WifiConfiguration> existingConfigs = wifiManager
.getConfiguredNetworks();
//找到之前已经配置的WiFi,找不到怎么办?,自己new一个呗(需要有密码,这里省略了,不是重点,网上一大堆)
for (WifiConfiguration existingConfig : existingConfigs) {
Log.e(TAG, "ssid=" + existingConfig.SSID);
if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
return existingConfig;
}
}
}
return null;
}
完结~~~