android,wifi连接功能开发,踩过的坑

前段时间做的一个小项目,是关于wifi连接功能的,在此做个小总结,借鉴了网上很多前辈的开发经验,所以这里分享一下,欢迎大家沟通交流。我们使用的google公开给第三方app使用的接口,基本全部连接功能都是使用WifiManager完成,更偏底层的WifiService等类未涉及,公司禁止上传源码,所以主要的叙述是踩坑记录和其中比较关键点的描述。

1)最关键的一个类:WifiManager
获取WifiManager时尽量使用Application,不要使用activity,有前辈叙述说这样可以避免内存泄漏。

2)获取扫描结果
isWifiEnabled()&&mWifimanager.startScan(),首先需要判断当前wifi是否开启,然后再开启扫描,注册广播,action:WifiManager.NETWORK_STATE_CHANGED_ACTION,2-3s后可以接收到wifi扫描结果,android6.0以上要求必须打开GPS才能获取扫描结果,所以没有扫描结果的基本上是因为你的GPS没有打开。

3)忘记密码
首先找到对应的ssid的WifiConfiguration(输入密码连接时代码创建),然后mWifiManager.removeNetwork(configuration.networkId) && mWifiManager.saveConfiguration(); 这里有个坑的,你只能忘记自己创建的WifiConfiguration,比如你通过手机设置中的wifi系统连接了热点iphone01,然后你想在自己的代码中去忘记热点iphone01,肯定是不可以的。
即使你想自己创建iphone01的配置文件去新建连接,也是无法连接成功的, mWifiManager.addNetwork(configuration)会返回-1,无法连接。

  1. 获取已连接wifi的ssid
    刚开始使用的方法 WifiInfo = mWifiManager.getConnectionInfo(),WifiInfo .getSSID(),可测试发现这种方式很不准确,经常wifi断开的还保留着上次的连接信息,所以这种方式无法准确的判断wifi是否已连接,我们使用了mConnectivityManager.getActiveNetworkInfo()判断当前网络是否已连接。

5)wifi扫描频率
系统wifi界面扫描频率基本是10s一次,所以在我们自己的app界面,可以设置扫描频率为10s左右一次,但注意不能过多,不然会出问题的。每次连接成功后,实际上会收到两次连接成功的广播,如果在连接成功后加入开启扫描的逻辑,要额外处理一下,不然一不小心就会出现扫描频率过多的情况。
这里一定要注意不要扫描太频繁,我刚开发时由于接收连接成功的广播有两三处,当时每次都开启扫描,导致短时间内大量调用mWifiManager,startScan方法的情况,然后把android系统 wifi 搞崩了的现象,导致系统wifi 也无法使用。虽然系统wifi崩溃是偶现,不能百分之百确认是扫描太频繁导致的,也有可能是我们的app连接和系统wifi连接冲突导致的,但关系肯定是很大的。

6)关于连接失败
通过监听网络状态变化的广播WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)来确认是否连接成功,这里网上很多,比较简单。
但连接失败就比较难确认了,可能是密码错误,也可能是热点限制连接数量,也有可能就是单纯的这此次连接没成功,密码正确连接失败的现象也会遇到呀,wifi这块本身就比较坑。
密码错误,监听广播

if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
                int res = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 123);
                SupplicantState state = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
                Log.i(TAG, "onReceive: SupplicantState--state = "+state.toString());
                if (res == WifiManager.ERROR_AUTHENTICATING && mCurrentWifiConfiguration != null) {
                    Log.i(TAG, " 密码错误 ");
                    mCurrentWifiConfiguration = null;
                    if (mWifiConnectTimeOutTimer != null && mWifiConnectTimeOutTimer.isRunning()) {
                        mWifiConnectTimeOutTimer.stop();
                    }
                    mWifiEvent.onErrorAuthenticating();
                } else if (state == SupplicantState.DISCONNECTED && mCurrentWifiConfiguration != null) {
                    Log.i(TAG, "count_disconnected = : " + count_disconnected);
                    count_disconnected++;
                    if (count_disconnected > 5) {
                        Log.i(TAG, " 网络连接失败 --count_disconnected>5");
                        mCurrentWifiConfiguration = null;
                        if (mWifiConnectTimeOutTimer != null && mWifiConnectTimeOutTimer.isRunning()) {
                            mWifiConnectTimeOutTimer.stop();
                        }
                        mWifiEvent.onConnectFail();
                    }
                }
            }

这块不插代码讲不清楚呀,代码和注释比较清晰,判断密码错误的方法是个过时的方法,不准确,经常出现密码错了但是没判断出来的情况,这里暂未找到其他更好的方法,知道的网友可以交流分享一下,万分感谢。如果判断不出来失败原因就直接归类为连接失败了,木办法,就是这么蠢。
代码中可以看到加了连接超时mWifiConnectTimeOutTimer,这个很必要的,因为会出现开始连接后,没有成功或失败的广播的现象,不能一直处于连接中吧,所以超时一定要加。
*
遗留问题:
int netId = mWifiManager.addNetwork(configuration);
偶现netId 为-1的情况,此时是无法连接热点的,只能再次输入密码连接。热点系统wifi未保存,非与系统wifi的冲突导致,一般重新打开就能解决问题,可以连接成功。网上搜到有说是WifiConfiguration构建有问题,但试了下他的还是不行,有兴趣的可以交流下。

你可能感兴趣的:(android,wifi连接功能开发,踩过的坑)