【android WiFi 切换】如何实现WiFi切换(支持AndroidQ及以上)

AndroidQ及以上如何实现WiFi切换

  • 背景
  • 新版API简介(可跳过)
  • 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;
}

完结~~~

你可能感兴趣的:(方案,android,前端,android,java,网络)