android 4.4 wifi 模块开发总结(电视盒子)

本文总结了在Android 4.4系统下开发WiFi模块的难点和解决方案,包括判断WiFi状态、扫描WiFi、连接WiFi、处理重名SSID等问题,并探讨了系统在4.4版本与6.0版本间的差异。通过数据库保存WiFi状态,监听广播来判断连接成功与否,并提供了部分代码片段。在自动连接和WiFi状态判定方面存在一些不足,如判定重名方法不准确,扫描可能卡住等。
摘要由CSDN通过智能技术生成

 

        最近6.0的盒子的应用开发已经告一段落了,接到的新需求就是想办法让公司以前发出去的4.4的盒子也得兼容应用。把应用装到4.4盒子上,发现也就文件读取,网络(有线无线),蓝牙,恢复出厂设置这几个模块不能用了,也就是用到6.0的jar包的都不行了。

        6.0wifi,系统有提供jar包,有 WifiTracker,AccessPoint这两个关键类,具体分析等有机会总结,但4.4是没有WifiTracker,AccessPoint这个类放的路径也不一样,导致系统底层提供jar包开发有点困难。所以应用层模拟一个wifi模块出来。结合了其他人的一些成果,也算鼓捣出来一款

4.4wifi开发的难点:

1.如何判定wifi是否打开

2.在wifi打开后扫描wifi

3.判定wifi扫描成功,或得扫描结果

4.确定wifi的各种状态(保存,连接,密码错误等等)

5.连接wifi(有密码与无密码)

6.忘记wifi

7.如何判定wifi已经连接成功(获得ip,网关,子网掩码)

8.wifi要是重名怎么办也就是(ssid一样)

方案:

1.如何判定wifi是否打开

   //获取wifi是否已打开
    public boolean isOpen() {
        boolean isOpen = mWifiManager.isWifiEnabled();
        Log.e(TAG, "wifi是否已打开:" + isOpen);
        return isOpen;
    }

打开wifi

    //打开与关闭wifi
    public void openWifi(boolean isOpen) {
        mWifiManager.setWifiEnabled(isOpen);
    }

2.在wifi打开后扫描wifi

3.判定wifi扫描成功,或得扫描结果

4.确定wifi的各种状态(保存,连接,密码错误等等)

注册一个广播,可以处理这些问题

 public void registerReceiver() {
        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
        mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        mFilter.addAction("android.net.wifi.CONFIGURED_NETWORKS_CHANGE");
        mFilter.addAction("android.net.wifi.LINK_CONFIGURATION_CHANGED");
        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
        if (mReceiver == null) {
            mReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    //处理4.4的广播
                    handleEvent(intent);
                }
            };
        }
        Log.e(TAG, "==注册wifi广播==");
        context.registerReceiver(mReceiver, mFilter);
    }

//wifi是否打开成功的判定

 if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
            //当WiFi被打开、关闭、正在打开、正在关闭或者位置状态即wifi状态发生改变时系统会自动发送该广播,
            // 该广播会附带有两个值,一个是int型表示改变后的state,
            // 可通过字段EXTRA_WIFI_STATE获取,
            // 还有一个是int型的改变前的state(如果有的话)
            // 可通过字段EXTRA_PREVIOUS_WIFI_STATE获取
            // int before_state = intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, 0);
            int after_state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
            if (after_state == WifiManager.WIFI_STATE_ENABLED) {
                Log.e(TAG, "wifi当前状态:开启");
                scanWifi();
            } else if (after_state == WifiManager.WIFI_STATE_DISABLED) {
                Log.e(TAG, "wifi当前状态:关闭");
                Log.e(TAG, "正在打开wifi");
                openWifi(true);
            }
        } 

//判定扫描成功,获取扫描结果

else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
            scanCompleted = true;
            //获得扫描结果
            List<ScanResult> scanResults = mWifiManager.getScanResults();
            // 得到配置好的网络连接
            List<WifiConfiguration> configuredNetworks = mWifiManager.getConfiguredNetworks();
            if (configuredNetworks != null && configuredNetworks.size() > 0) {
                Log.e(TAG, "得到配置好的网络连接::" + configuredNetworks.toString());
            } else {
                //没有任何配置好的wifi,处理是清空数据库
                Log.e(TAG, "没有任何配置好的wifi,处理是清空数据库");
                wifiDbManager.clearWifiDb();
            }
            if (scanResults != null) {
                List<ScanResult> scanResultList = sortByLevel(scanResults);
                List<Wifi4_0InfoBean> wifiInfoBeanList = new ArrayList<>();
                for (ScanResult re : scanResultList) {
                    //发现扫描的结果出现SSID=""的情况,暂时不清楚原因,过滤这种情况
                    if (re != null && !TextUtils.isEmpty(re.SSID)) {
                        Log.e(TAG, "扫描得到的wifi结果::" + re.toString());
                        Wifi4_0InfoBean wifiInfoBean = new Wifi4_0InfoBean(re);
                        //判断wifi的加密方式
                        wifiInfoBean.setSecurity(getWifiSecurity(re));
                        //设置wifi的强度
                        wifiInfoBean.setLevel(getSignalLevel(re.level));
                        //设置连接状态
                        String state = wifiDbManager.getWifiStatus(re.SSID, re.BSSID);
                        wifiInfoBean.setWifiStatus(state);
                        if (state.equals(Wifi4_0State.CONNECTED)){
                            if (!hasConectWifi(re.SSID,re.BSSID)){
                                wifiInfoBean.setWifiStatus(Wifi4_0State.STATUS_SAVED);
                            }
                            wifiInfoBeanList.add(0,wifiInfoBean);
                        }else if (!state.equals(Wifi4_0State.STATUS_NONE)){
                            if (wifiInfoBeanList.size()==0){
                                wifiInfoBeanList.add(wifiInfoBean);
                            }else {
                                wifiInfoBeanList.add(1,wifiInfoBean);
                            }
                        }else {
                            wifiInfoBeanList.add(wifiInfoBean);
                        }
                    }
                    //通过wpa/wpa2进行保护:[WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS]
                    //通过WPA2进行保护:[WPA2-PSK-CCMP][ESS]
                    //通过wpa/wpa2进行保护(可使用WPS)[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][WPS][ESS]
                    //获得接入点的数据:
                }
                Log.e(TAG, "扫描wifi结束:根据强度排序得到wifi的条目" + wifiInfoBeanList.toString());
                if (callback != null) {
                    callback.getWifiList(wifiInfoBeanList);
                }
            }
        }

wifi的状态,因为6.0存在一个accesspoint这个类,这个类封装了wifi的状态,但现在是4.0,4.0底层也有这个类,但一系统层我拿不到,而好像也没封装。所以我就拿了net里的一些状态和自己模拟了一些状态。

package com.ishuidi.boxproject.module.more.network.bean;

/**
 * @创建人:hcy
 * @创建时间:2018/10/29
 * @作用描述:Function
 **/
//wifi4_0状态
public interface Wifi4_0State {
    //准备开始数据连接设置
    static  final  String  IDLE="IDLE";
    //扫描中
    static  final  String  SCANNING="SCANNING";
    //正在连接中
    static  final  String  CONNECTING="CONNECTING";
    //进行身份验证
    static  final  String  AUTHENTICATING="AUTHENTICATING";
    //正在获取Ip地址
    static  final  String  OBTAINING_IPADDR="OBTAINING_IPADDR";
    //已经连接
    static  final  String  CONNECTED="CONNECTED";
    //IP通信暂停
    static  final  String  SUSPENDED="SUSPENDED";
    //当前正在断开数据连接
    static  final  String  DISCONNECTING="DISCONNECTING";
    //已断开
    static  final  String  DISCONNECTED="DISCONNECTED";

    //连接失败
    static  final  String  FAILED="FAILED";
    //对这个网络的访问被阻塞
    static  final  String  BLOCKED="BLOCKED";
    //链接的连通性很差
    static  final  String  VERIFYING_POOR_LINK="VERIFYING_POOR_LINK";
    //检查网络是否为专用门户
    static  final  String  CAPTIVE_PORTAL_CHECK="CAPTIVE_PORTAL_CHECK";

    //无状态
    static  final  String  STATUS_NONE="STATUS_NONE";
    //身份验证出现问题
    static  final  String  STATUS_PASSWORD_ERROR="STATUS_PASSWORD_ERROR";

    //已保存
    static  final  String  STATUS_SAVED="STATUS_SAVED";

    //未启用
    static  final  String STATUS_WIFI_UNABLE="STATUS_WIFI_UNABLE";

}

最后四种状态是我模拟的。

如何判定状态:1.一个大前提需要知道:当4.4盒子同时连接有线和wifi的时候,系统默认用有线,wifi是不启用的,及时输了密码

                            2.状态的保存:我是采取数据库保存wifi的状态的

wifi状态的判定除了输错密码,是通过这个广播判定的:

if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
            //判断wifi是否连接上
            NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            if (null != info) {
                NetworkInfo.DetailedState state = info.getDetailedState();
                String ssid = mWifiManager.getConnectionInfo().getSSID().replaceAll("\"", "");
                String bssid = mWifiManager.getConnectionInfo().getBSSID();
                Toast.makeText(context, "wifi状态变化: " + state.name() + "???" + ssid + "???" + bssid, Toast.LENGTH_LONG).show();
                Log.d(TA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值