Android 6.0 关于WiFi的改变

https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-network
http://m.blog.csdn.net/article/details?id=51042851
http://seewhy.leanote.com/post/Android-6.0-Changes
最近发现在安卓6.0的机子上,无法切换到指定WiFi,与其说是安卓6.0的问题,不如说是自己以前的代码不符合规范。

问题:

连接到指定WiFi,我之前使用的代码如下:

// 添加一个网络并连接
    public void addNetwork(WifiConfiguration wcg) {
        int wcgID = mWifiManager.addNetwork(wcg);
        boolean b = mWifiManager.enableNetwork(wcgID , true);
     }

在Android 6.0 中WiFiManager addNetwork(WifiConfiguration config),添加同一ssid时会返回-1,这个时候你再将这个-1 (NetWorkId)传进enableNetwork(-1,true),肯定连不上WiFi。

分析原因

在官方的文章(这篇文章翻译的不错)中,介绍了关于安卓6.0中有关WiFi的改变。如下:

Wi-Fi and Networking Changes

This release introduces the following behavior changes to the Wi-Fi and networking APIs.

  • Your apps can now change the state of WifiConfiguration objects only if you created these objects. You are not permitted to modify or delete WifiConfiguration objects created by the user or by other apps.

  • Previously, if an app forced the device to connect to a specific Wi-Fi network by using enableNetwork() with the disableAllOthers=true setting, the device disconnected from other networks such as cellular data. In This release, the device no longer disconnects from such other networks. If your app’s targetSdkVersion is “20” or lower, it is pinned to the selected Wi-Fi network. If your app’s targetSdkVersion is “21” or higher, use the multinetwork APIs (such as openConnection(), bindSocket(), and the new bindProcessToNetwork() method) to ensure that its network traffic is sent on the selected network.

解释:
原因就是第一条,在扫描WiFi列表时,系统会自动创建曾经连接成功过的WiFi的WifiConfiguration ,使用addNetwork()添加这个WiFi时,就是改变了系统创建的WifiConfiguration对象,所以addNetwork()会返回-1。

在addNetwork的源码中发现:

 public int addNetwork(WifiConfiguration config) {
        if (config == null) {
            return -1;
        }
        //这里改变了WifiConfiguration
        config.networkId = -1;
        return addOrUpdateNetwork(config);
    }

在Android 5.1系统中,即使已经存在指定SSID的WifiConfiguration对象,再次使用addNetwork()添加相同的网络,添加成功而且返回的ID和添加之前的一样,我猜测是返回了系统的WifiConfiguration对象,虽然有改变WifiConfiguration对象

但是手动在WLAN设置中,删除网络A,再次连接网络A,发现网络A的WifiConfiguration的ID,不一样了,如果addNetwork()中不是返回WifiConfiguration对象,那么ID应该不一样。

解决方法:

下面只是一个大概思路,代码并不完整

private void Wificonnect() {
        // 连接到外网
        WifiConfiguration mWifiConfiguration;
        WifiManager mWifiManager = new WifiAdmin(this);
        String SSID = wifiName.replace("+", " ");
        String password = wifiPwd;
        //检测指定SSID的WifiConfiguration 是否存在
        WifiConfiguration tempConfig = IsExsits(SSID);
        if (tempConfig == null) {
            //创建一个新的WifiConfiguration ,CreateWifiInfo()需要自己实现
            mWifiConfiguration = CreateWifiInfo(SSID, password, 3);
            int wcgID = mWifiManager.addNetwork(mWifiConfiguration );
            boolean b = mWifiManager.enableNetwork(wcgID, true);
        } else {
        //发现指定WiFi,并且这个WiFi以前连接成功过
            mWifiConfiguration = tempConfig;
            boolean b = mWifiManager.enableNetwork(mWifiConfiguration .networkId, true);
        }

}

//判断曾经连接过得WiFi中是否存在指定SSID的WifiConfiguration 
public WifiConfiguration IsExsits(String SSID) {
        List<WifiConfiguration> existingConfigs = mWifiManager
                .getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                return existingConfig;
            }
        }
        return null;
}

你可能感兴趣的:(android,Wi-Fi)