Android 开发 正常WiFi功能开发 与 WiFi热点开发详解

前言

    此篇博客讲解WiFi正常功能开发与热点功能开发

权限

不管是WiFi正常功能还是WiFi热点都需要以下权限,Android5.0还需要动态权限

   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

WiFi正常功能扫描/连接/断开)

初始化WiFi管理

操作WiFi的基础类,所有的WiFi操作都需要使用这个管理类

WifiManager mWifiManager = WifiManager)getApplicationContext).getSystemServiceContext.WIFI_SERVICE);

判断WiFi状态

这个是判断设备的WiFi硬件状态,一共有已经几种设备状态:

WIFI_STATE_DISABLED    WiFi已经禁用
WIFI_STATE_DISABLING     正在禁用WiFi中
WIFI_STATE_ENABLED     WiFi已经启用
WIFI_STATE_ENABLING      正在启用WiFi中
WIFI_STATE_UNKNOWN      设备状态未知或者没有WiFi硬件支持)

    if mWifiManager.getWifiState) == WifiManager.WIFI_STATE_DISABLED){
        Log.eTAG, "WiFi已经启用");
    }

判断WiFi是否开启

这是官方提供的更快捷判断WiFi是否开启的方法

    if mWifiManager.isWifiEnabled)){
        Log.eTAG, "WiFi已经开启");
    }else {
        Log.eTAG, "WiFi已经关闭");
    }

开启或者关闭WiFi

用此方法开启WiFi会有一个系统弹窗提示用户手动开启WiFi.

mWifiManager.setWifiEnabledtrue); //false为关闭

 搜索WiFi与获取WiFi设备列表

private void scan){
        mWifiManager.startScan); //搜索WiFi,在这个代码的注释里有说明搜索过程是异步的
        Handler handler = new Handler);
        handler.postDelayednew Runnable) {
            @Override
            public void run) {
                List<ScanResult> list =  mWifiManager.getScanResults); //获取WiFi列表
                for ScanResult scanResult : list){
                    Log.eTAG, "==================================");
                    Log.eTAG, "scan: wifi 名称="+scanResult.SSID);
                    Log.eTAG, "scan: wifi WiFi地址="+scanResult.BSSID);
                    Log.eTAG, "scan: wifi 加密方式="+scanResult.capabilities);

                }
            }
        },1000);
    }

 开始搜索是一个异步的过程,你可以直接获取WiFi列表有可能还是上次的搜索结果),也可以写个Handler等待几秒在获取WiFi列表.

注意一! mWifiManager.getScanResults) 得到的List里面的数据其实是一直会变化的! 意思是计算你获取到了这个list,在WiFi的底层代码里依然会修改/增加/删除这个list里的数据

注意二! mWifiManager.getScanResults) 得到的List里面的数据会出现重复/空名/个别值为null的问题,这是正常的.所以WiFi的难点不是连接与搜索,而是清洗数据

结果:

WifiActivity: ==================================
WifiActivity: scan: wifi 名称=WETOOL_2.4G
WifiActivity: scan: wifi WiFi地址=08:9b:4b:9d:25:b5
WifiActivity: scan: wifi 加密方式=[WPA2-PSK+FT/PSK-CCMP][ESS]
WifiActivity: ==================================
WifiActivity: scan: wifi 名称=2_5g
WifiActivity: scan: wifi WiFi地址=d0:ee:07:59:64:18
WifiActivity: scan: wifi 加密方式=[WPA-PSK-CCMP][WPA2-PSK-CCMP][ESS]
WifiActivity: ==================================
WifiActivity: scan: wifi 名称=喵星人的WiFi
WifiActivity: scan: wifi WiFi地址=6c:88:14:f4:f3:5d
WifiActivity: scan: wifi 加密方式=[WPA2-PSK-CCMP][ESS]

ScanResult可以获取的信息

ScanResult是搜索到WiFi列表后获取的单个WiFi信息,里面包含了一些信息需要了解一下注意,如果你看源码会发现有很多信息是隐藏的无法调用的.那些变量都是系统级别的API才能调用,这里只说明可以看到的信息)

                    CharSequence area = scanResult.venueName;   //WiFi接入点的地点名称
                    int frequency = scanResult.frequency;       //频率
                    long refreshTime = scanResult.timestamp;    //此WiFi最新的刷新时间戳
                    int level = scanResult.level;               //信号强度
                    String encryption = scanResult.capabilities;//加密方式 例如:WEP/WAP/WAP2
                    String address = scanResult.BSSID;          //WiFi的地址
                    String name = scanResult.SSID;              //WiFi的名称

连接指定的WIiFi网络

这段流程比较长,大致是这样的:

1.搜索WiFi,找到指定WiFi 获取名称/地址/加密方式,以及你自己知道的WiFi密码

2.创建WiFi配置信息WifiConfiguration, 添加WiFi名称,地址

3.在根据加密方式以对应的方式添加密码到WifiConfiguration

4.将WiFi配置WifiConfiguration,添加到以配置的网络列表里addNetworkwifiConfiguration);

5.获取已经配置好的网络列表mWifiManager.getConfiguredNetworks);,找到指定WiFi,获取id

6.断开现在正在连接的WiFi,输入id启用设置好的WiFi,重新连接

注意! scanResult.BSSID  这个BSSID其实动态生成的路由地址,不可以依靠这来判断wifi的唯一性. 所以用SSID加BSSID来锁定一个WiFi是不现实的.因为有时候BSSID其实是null的.只能使用SSID来判断WiFi,遇到重名WiFi没有什么办法

public void scan){
        List<ScanResult> list =  mWifiManager.getScanResults); //获取WiFi列表
        Log.eTAG, "list 长度="+list.size));
        for ScanResult scanResult : list){
            if scanResult.SSID.equals"My_5g")){ //找到我们需要的WiFi
                connectionWifiscanResult.SSID,"winteam0901", scanResult.capabilities); //连接它
            }

        }
    }

    /**
     * 连接WiFi的方法
     * @param ssid wifi名称
     * @param password WiFi密码
     * @param capabilities 加密方式
     */
    public void connectionWifiString ssid, String password, String capabilities) {
        WifiConfiguration wifiConfiguration = new WifiConfiguration);
        ssid = """ + ssid + """;          //WiFi的名称配置需要加引号
        password = """ + password + """;  //WiFi的密码配置需要加引号
        wifiConfiguration.SSID = ssid;
        if capabilities.contains"WPA")) {
            wifiConfiguration.preSharedKey = password;

        } else if capabilities.contains"WEP")) {
            wifiConfiguration.wepKeys[0] = password;
            wifiConfiguration.wepTxKeyIndex = 0;
            wifiConfiguration.allowedKeyManagement.setWifiConfiguration.KeyMgmt.NONE);
            wifiConfiguration.allowedGroupCiphers.setWifiConfiguration.GroupCipher.WEP40);

        } else if capabilities.contains"OPEN")) {
            wifiConfiguration.allowedKeyManagement.setWifiConfiguration.KeyMgmt.NONE);

        }
        mWifiManager.addNetworkwifiConfiguration);
        List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks);
        for WifiConfiguration item : wifiConfigurationList) {
            if item.SSID == null) {
                continue;
            }
            if item.SSID.equalsssid)) {
                mWifiManager.disconnect); //断开连接
                mWifiManager.enableNetworkitem.networkId, true); //连接我们需要的WiFi
                mWifiManager.reconnect);   //重新连接
            }
        }
    }

获取已经配置密码并且保存的WiFi网络列表

上面的代码里有说明获取已经配置密码的WiFi网络列表的部分代码了,就是如下代码,但是这里在强调一下.他的使用情景与信息

1.WiFi是有暂存的,以记录密码的WiFi系统会保存起来,方便某个WiFi断开后自动重新连接这个配置列表里的其他WiFi

2.所以在如果要删除某个WiFi,你必需移除这个配置列表里的这个WiFi,如果只是断开操作将可能自动重连

3.这个配置列表还能告诉用户已经保存连接过所有WiFi的,用户直接点击后重新连接这个WiFi不需要再次输入密码)

4.你可以重新更新这个配置列表的WiFi密码

注意! 跟上面的一样 mWifiManager.getConfiguredNetworks) 得到的List里面的数据会出现重复/空名/个别值为null的问题.另外这里获取的WiFi数据是不含信号强度的.如果你需要信号强度就需要跟ScanResult数据进行对比后获取.

List<WifiConfiguration> configurationList = mWifiManager.getConfiguredNetworks); 

更新指定WiFi更换密码)

更新WiFi的方法主要是mWifiManager.updateNetworkitem);  但是请注意这个WiFi必须是已经保存配置的WiFi

  /**
     * 更新WiFi
     */
    public void undateWifiString ssid, String password) {
        List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks);
        for WifiConfiguration item : wifiConfigurationList) {
            if item.SSID == null) {
                continue;
            }
            if item.SSID.equals""" + ssid + """)) {
                item.preSharedKey = """ + password + """;
                mWifiManager.disconnect);
                int id = mWifiManager.updateNetworkitem);
                if id == -1) { //id如果等于 -1 就说明更新失败了
                    return;
                }
                mWifiManager.enableNetworkid, true); //启用连接WiFi
                mWifiManager.reconnect);
            }
        }
    }

移除指定WiFi

 注意! 这里的移除WiFi,只能移除自己的app保存的WiFi,如果是手机-设置-WiFi设置里手动添加的WiFi,你是无法移除的.

  /** 
     * 移除这个app保存的WiFi
     *
     * @param ssid
     */
    public void removeWifiString ssid) {
        mWifiManager.startScan);
        List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks);
        for WifiConfiguration item : wifiConfigurationList) {
            if item.SSID.equals""" + ssid + """)) {
                mWifiManager.disconnect);
                mWifiManager.removeNetworkitem.networkId);
                mWifiManager.reconnect);

            }
        }
    }

获取当前正在连接中的WiFi信息

public WifiInfo getConnectionInfo) {
        WifiInfo wifiInfo = mWifiManager.getConnectionInfo);
        wifiInfo.getSSID);//WiFi名称
        wifiInfo.getRssi);//信号强度
        wifiInfo.getIpAddress);//ip地址
        wifiInfo.getFrequency);//频率 比如2.4G(boolean is24G = frequency > 2400 && frequency < 2500;) 或者 5G (boolean is5G = frequency > 4900 && frequency < 5900;)的WiFi
        wifiInfo.getNetworkId);//id
        wifiInfo.getLinkSpeed);//网络链接速度
        wifiInfo.getSupplicantState);//获取请求状态
        return wifiInfo;
    }

  这里获取的ssid 是带引号的

  注意!获取正在连接中的WiFiInfo,这个数据是永远不会是空的,如果一次WiFi都没连接过那么它携带的数据会有空的,如果连接过然后又断开了,那么你在这里获取的就是之前连接的WiFi. 那么如何判断当前是否真的有连接WiFi呢?

很简单判断ip地址即可,这个地址是实时刷新的:

        if wifiInfo.getIpAddress) == 0){
            Log.eTAG, "getData: 当前未连接WiFi");
        }

增加引号和移除引号的方法

/**
     * 移除引号
     *
     * @param content
     * @return
     */
    public String removeQuotationMarksString content) {
        content = content.substring1, content.length) - 1);
        return content;

    }

    /**
     * 添加引号
     *
     * @param content
     * @return
     */
    public String addQuotationMarksString content) {
        content = """ + content + """;
        return content;
    }

格式化wifi信号值

 /**
     * WifiInfo.MIN_RSSI = -126;
     * WifiInfo.MAX_RSSI = 200;
     *
     * Quality     Excellent           Good            Fair            Poor
     * dBm        -30 ~ -61        -63 ~ -73     -75 ~ -85        -87 ~ -97
     *
     * @param rssi
     * @return
     */
    public static int formatLevelint rssi) {
        if rssi < -97){
            return 0;
        }else if rssi < -87){
            return 1;
        }else if rssi < -75){
            return 2;
        }else if rssi < -63){
            return 3;
        }else {
            return 4;
        }
    }

将WiFi的IP地址转换成Mac地址显示

/**
     * 将idAddress转化成string类型的Id字符串
     *
     * @param idString
     * @return
     */
    private static String getStringIdint idString) {
        StringBuffer sb = new StringBuffer);
        int b = idString >> 0) & 0xff;
        sb.appendb + ".");
        b = idString >> 8) & 0xff;
        sb.appendb + ".");
        b = idString >> 16) & 0xff;
        sb.appendb + ".");
        b = idString >> 24) & 0xff;
        sb.appendb);
        return sb.toString);
    }

获取WiFi状态

注册广播

        mIntentFilter = new IntentFilter);
        mIntentFilter.addAction"android.net.wifi.STATE_CHANGE");//WiFi状态变化
        mIntentFilter.addAction"android.net.wifi.WIFI_STATE_CHANGED");//WiFi开关状态
        mWiFiChangeReceiver = new WiFiChangeReceiver);
        registerReceivermWiFiChangeReceiver,mIntentFilter);

接收广播处理

class WiFiChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceiveContext context, Intent intent) {

            if intent.getAction).equalsWifiManager.WIFI_STATE_CHANGED_ACTION)) {
                int switchState = intent.getIntExtraWifiManager.EXTRA_WIFI_STATE, 0);//得到WiFi开关状态值
                switch switchState) {
                    case WifiManager.WIFI_STATE_DISABLED://WiFi已关闭
                        WiFIStateData data1 = new WiFIStateData);
                        data1.time = mDf.formatSystem.currentTimeMillis));
                        data1.state = "WiFi关闭";
                        mDao.insertdata1);
                        EventBus.getDefault).postmsgData);
                        Log.eTAG, "WiFi关闭");
                        break;
                    case WifiManager.WIFI_STATE_DISABLING://WiFi关闭中
                        Log.eTAG, "WiFi关闭中");
                        break;
                    case WifiManager.WIFI_STATE_ENABLED://WiFi已开启
                        WiFIStateData data2 = new WiFIStateData);
                        data2.time = mDf.formatSystem.currentTimeMillis));
                        data2.state = "WiFi开启";
                        mDao.insertdata2);
                        EventBus.getDefault).postmsgData);
                        Log.eTAG, "WiFi开启");
                        break;
                    case WifiManager.WIFI_STATE_ENABLING://WiFi开启中
                        Log.eTAG, "WiFi开启中");
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN://WiFi状态未知
                        WiFIStateData data3 = new WiFIStateData);
                        data3.time = mDf.formatSystem.currentTimeMillis));
                        data3.state = "WiFi状态未知";
                        mDao.insertdata3);
                        EventBus.getDefault).postmsgData);
                        Log.eTAG, "WiFi状态未知");
                        break;
                    default:
                        break;
                }
            }

                if intent.getAction).equalsWifiManager.NETWORK_STATE_CHANGED_ACTION)){ //网络状态改变行为
                    Parcelable parcelableExtra = intent.getParcelableExtraWifiManager.EXTRA_NETWORK_INFO);//得到信息包
                    if parcelableExtra != null){、蓝牙——
                        NetworkInfo networkInfo = NetworkInfo)parcelableExtra;//得到网络信息
                        NetworkInfo.DetailedState detailedState = networkInfo.getDetailedState);
                        switch detailedState){
                            case CONNECTED:
                                mDisconnectState = true;
                                WiFIStateData data4 = new WiFIStateData);
                                data4.time = mDf.formatSystem.currentTimeMillis));
                                data4.state = "已经连接";
                                mDao.insertdata4);
                                EventBus.getDefault).postmsgData);
                                Log.eTAG, "已经连接");
                                break;
                            case DISCONNECTED:
                                if mDisconnectState){
                                    mDisconnectState = false;
                                    WiFIStateData data5 = new WiFIStateData);
                                    data5.time = mDf.formatSystem.currentTimeMillis));
                                    data5.state = "已经断开";
                                    mDao.insertdata5);
                                    EventBus.getDefault).postmsgData);
                                    Log.eTAG, "已经断开");
                                }
                                break;
                            case IDLE:

                                WiFIStateData data6 = new WiFIStateData);
                                data6.time = mDf.formatSystem.currentTimeMillis));
                                data6.state = "空闲中";
                                mDao.insertdata6);
                                EventBus.getDefault).postmsgData);
                                Log.eTAG, "空闲中");

                                break;
                            case AUTHENTICATING:

                                WiFIStateData data7 = new WiFIStateData);
                                data7.time = mDf.formatSystem.currentTimeMillis));
                                data7.state = "认证中";
                                mDao.insertdata7);
                                EventBus.getDefault).postmsgData);
                                Log.eTAG, "认证中");

                                break;
                            case BLOCKED:

                                WiFIStateData data8 = new WiFIStateData);
                                data8.time = mDf.formatSystem.currentTimeMillis));
                                data8.state = "认证失败";
                                mDao.insertdata8);
                                EventBus.getDefault).postmsgData);
                                Log.eTAG, "认证失败");

                                break;
                            case CAPTIVE_PORTAL_CHECK:

                                WiFIStateData data9 = new WiFIStateData);
                                data9.time = mDf.formatSystem.currentTimeMillis));
                                data9.state = "连接检查";
                                mDao.insertdata9);
                                EventBus.getDefault).postmsgData);
                                Log.eTAG, "连接检查");

                                break;
                            default:
                                break;
                        }
                    }

            }

        }
    }

WiFi设备信息的数据清洗

  上面的WiFi内容都是WiFi基本玩法,下面才是玩自定义WiFi的难点。  

  Android提供的WiFi框架会因为WiFi设备原因,显示很多同名WiFi。并且getConfiguredNetworks 与  getConnectionInfo 与 getScanResults 三种数据获取后都有相同的数据,数据比较混乱重复,甚至还有空名称的WiFi。所以,我们需要清洗它,这是自定义WiFi功能的难点。

1.创建一个清洗后数据保存的bean

package com.zh.zwifidemo.wifi;

import java.util.List;

public class WifiDataBean {
    private ConnectionWifi connectionWifi;  //当前正在连接的WiFi
    private List<ConfigWifi> configWifiList;//已经配置过的WiFi
    private List<OtherWifi> otherWifiList;  //搜索到的其他WiFi


    public ConnectionWifi getConnectionWifi) {
        return connectionWifi;
    }

    public void setConnectionWifiConnectionWifi connectionWifi) {
        this.connectionWifi = connectionWifi;
    }

    public List<ConfigWifi> getConfigWifiList) {
        return configWifiList;
    }

    public void setConfigWifiListList<ConfigWifi> configWifiList) {
        this.configWifiList = configWifiList;
    }

    public List<OtherWifi> getOtherWifiList) {
        return otherWifiList;
    }

    public void setOtherWifiListList<OtherWifi> otherWifiList) {
        this.otherWifiList = otherWifiList;
    }

    public class ConnectionWifi{
        private String ssid;
        private Integer level; //信号强度
        private Integer ipAddress;
        private Integer frequency;//频率

        public String getSsid) {
            return ssid;
        }

        public void setSsidString ssid) {
            this.ssid = ssid;
        }

        public Integer getLevel) {
            return level;
        }

        public void setLevelInteger level) {
            this.level = level;
        }

        public Integer getIpAddress) {
            return ipAddress;
        }

        public void setIpAddressInteger ipAddress) {
            this.ipAddress = ipAddress;
        }

        public Integer getFrequency) {
            return frequency;
        }

        public void setFrequencyInteger frequency) {
            this.frequency = frequency;
        }
    }

    public class ConfigWifi{
        private String ssid;
        private Integer level; //信号强度
        /*
        public static final int CURRENT = 0; 已连接
        public static final int DISABLED = 1; 停用,错误密码
        public static final int ENABLED = 2; 已保存,未连接
        */
        private Integer state;
        private String capabilities;

        public String getSsid) {
            return ssid;
        }

        public void setSsidString ssid) {
            this.ssid = ssid;
        }

        public Integer getLevel) {
            return level;
        }

        public void setLevelInteger level) {
            this.level = level;
        }

        public Integer getState) {
            return state;
        }

        public void setStateInteger state) {
            this.state = state;
        }

        public String getCapabilities) {
            return capabilities;
        }

        public void setCapabilitiesString capabilities) {
            this.capabilities = capabilities;
        }
    }

    public class OtherWifi{
        private String ssid;
        private Integer level; //信号强度
        private String capabilities;//安全形式

        public String getSsid) {
            return ssid;
        }

        public void setSsidString ssid) {
            this.ssid = ssid;
        }

        public Integer getLevel) {
            return level;
        }

        public void setLevelInteger level) {
            this.level = level;
        }

        public String getCapabilities) {
            return capabilities;
        }

        public void setCapabilitiesString capabilities) {
            this.capabilities = capabilities;
        }
    }


}

  2.清洗将所有获取的WiFi数据清洗,最后返回我们需要的bean数据

public WifiDataBean getWifiBean) {
        WifiDataBean wifiDataBean = new WifiDataBean);
        WifiInfo wifiInfo = mWifiManager.getConnectionInfo);
        List<ScanResult> scanResultList = new ArrayList<>);
        List<WifiConfiguration> configurationList = new ArrayList<>);
        scanResultList.addAllmWifiManager.getScanResults));
        configurationList.addAllmWifiManager.getConfiguredNetworks));


        List<WifiDataBean.ConfigWifi> configWifiList = new ArrayList<>);
        List<WifiDataBean.OtherWifi> otherWifiList = new ArrayList<>);

        /*
            处理当前正在连接中的WiFi
         */
        if wifiInfo.getIpAddress) == 0) {
            wifiDataBean.setConnectionWifinull);
        } else {
            WifiDataBean.ConnectionWifi connectionWifi = wifiDataBean.new ConnectionWifi);
            connectionWifi.setSsidwifiInfo.getSSID));
            connectionWifi.setLevelwifiInfo.getRssi));
            connectionWifi.setIpAddresswifiInfo.getIpAddress));
            connectionWifi.setFrequencywifiInfo.getFrequency));
            wifiDataBean.setConnectionWificonnectionWifi);
        }

        /*
            处理已经配置过的WiFi
         */
        if configurationList.isEmpty)) {
            wifiDataBean.setConfigWifiListconfigWifiList);

        } else {
            for int i = 0; i < configurationList.size); i++) { //除去null的WiFi
                WifiConfiguration configuration = configurationList.geti);
                if configuration.SSID == null) {
                    configurationList.removeconfiguration);
                }
            }

            if wifiDataBean.getConnectionWifi) != null) {
                for int i = 0; i < configurationList.size); i++) { //去除正在连接的WiFi item
                    WifiConfiguration configuration = configurationList.geti);
                    if configuration.SSID.equalswifiDataBean.getConnectionWifi).getSsid))) {
                        configurationList.removeconfiguration);
                    }
                }
            }

            for int i = 0; i < configurationList.size); i++) { //除去重复的WiFi
                WifiConfiguration configuration = configurationList.geti);
                for int j = i + 1; j < configWifiList.size); j++) {
                    WifiConfiguration item = configurationList.getj);
                    if configuration.SSID.equalsitem.SSID)) {
                        configurationList.removeitem);
                    }

                }
            }

            for int i = 0; i < configurationList.size); i++) { //添加配置过的WiFi数据
                WifiConfiguration configuration = configurationList.geti);
                WifiDataBean.ConfigWifi configWifi = wifiDataBean.new ConfigWifi);
                configWifi.setSsidconfiguration.SSID);
                configWifi.setStateconfiguration.status);
                for int j = 0; j < scanResultList.size); j++) {
                    ScanResult scanResult = scanResultList.getj);
                    if removeQuotationMarksconfiguration.SSID).equalsscanResult.SSID)) {
                        configWifi.setLevelscanResult.level);
                    }
                }
                if configWifi.getLevel) == null) {
                    configWifi.setLevel-98);

                }
                if configuration.preSharedKey != null && !configuration.preSharedKey.equals"")) {
                    configWifi.setCapabilities"WPA");
                } else if configuration.wepKeys[0] != null && !configuration.wepKeys[0].equals"")) {
                    configWifi.setCapabilities"WEP");
                } else {
                    configWifi.setCapabilities"OPEN");
                }
                configWifiList.addconfigWifi);
            }
            wifiDataBean.setConfigWifiListconfigWifiList);
        }

        /*
            设置其他WiFi
         */
        if scanResultList.isEmpty)) {
            wifiDataBean.setOtherWifiListotherWifiList);

        } else {
            for int i = 0; i < scanResultList.size); i++) { //去除null
                ScanResult scanResult = scanResultList.geti);
                if scanResult.SSID == null) {
                    scanResultList.removescanResult);
                }
            }

            if wifiDataBean.getConnectionWifi) != null){
                for int i = 0; i < scanResultList.size); i++) { //去除已连接的
                    ScanResult scanResult = scanResultList.geti);
                    if scanResult.SSID.equalsremoveQuotationMarkswifiDataBean.getConnectionWifi).getSsid)))) {
                        scanResultList.removescanResult);
                    }
                }
            }

            for int i = 0; i < scanResultList.size); i++) { //去除已配置的
                ScanResult scanResult = scanResultList.geti);
                for int j = 0; j < configWifiList.size); j++) {
                    WifiDataBean.ConfigWifi configWifi = configWifiList.getj);
                    if removeQuotationMarksconfigWifi.getSsid)).equalsscanResult.SSID)) {
                        scanResultList.removescanResult);
                    }
                }
            }

            for int i = 0; i < scanResultList.size); i++) { //去除重复的
                ScanResult scanResult = scanResultList.geti);
                for int j = i + 1; j < scanResultList.size); j++) {
                    ScanResult item = scanResultList.getj);
                    if scanResult.SSID.equalsitem.SSID)) {
                        scanResultList.removeitem);
                    }
                }
            }

            for int i = 0; i < scanResultList.size); i++) {
                ScanResult scanResult = scanResultList.geti);
                WifiDataBean.OtherWifi otherWifi = wifiDataBean.new OtherWifi);
                otherWifi.setSsidscanResult.SSID);
                otherWifi.setLevelscanResult.level);
                otherWifi.setCapabilitiesscanResult.capabilities);
                otherWifiList.addotherWifi);
            }
            wifiDataBean.setOtherWifiListotherWifiList);
        }
        return wifiDataBean;
    }

WIFI热点

注意WiFi热点除了WiFi权限以外,如果要创建wifi热点还需要一个系统权限 android.permission.WRITE_SETTINGS。

但是这种系统权限在6.0版本后无法直接静态或者动态授权(十分无语)。所以在下面的代码中setPermissions方法就是添加设置权限的办法。

/*
content:创建WiFi热点class
time:2018-7-23 11:23
build:
 */

public class WiFiAP {
    private static WiFiAP mWiFiAP;
    private static WifiManager mWifManager;
    private WiFiAP){}

    public static WiFiAP getI){
        if mWiFiAP == null){
            mWiFiAP = new WiFiAP);
        }
        return mWiFiAP;
    }

    /**
     * 手动得到系统权限的方法,提供给外部启动系统权限界面,以实现手动添加系统权限
     * @param context 外部activity的上下文
     */
    public void setPermissionsContext context){
        Intent intent = new IntentSettings.ACTION_MANAGE_WRITE_SETTINGS);
        intent.setDataUri.parse"package:" + context.getPackageName)));
        context.startActivityintent);

    }

    /**
     * 打开热点并且创建WiFi热点的方法
     * @param context 外部上下文
     * @param ssid 要创建WiFi热点的账号名称
     * @param password 要创建WiFi热点的密码
     * 注意,此方法直接使用WPA2_PSK 的安全策略创建WiFi热点,低版本的Android系统如果需要使用请切换。
     */
    @SuppressLint"MissingPermission")
    public void openWiFiAPContext context, String ssid, String password){

        mWifManager = WifiManager)context.getApplicationContext).getSystemServiceContext.WIFI_SERVICE);

        if mWifManager.isWifiEnabled)) {
            //如果wifi处于打开状态,则关闭wifi,
            mWifManager.setWifiEnabledfalse);
        }
        WifiConfiguration config = new WifiConfiguration);
        config.SSID = ssid;
        config.preSharedKey = password;
        config.hiddenSSID = false;//是否隐藏热点true=隐藏
        config.allowedAuthAlgorithms
                .setWifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证
        config.allowedGroupCiphers.setWifiConfiguration.GroupCipher.TKIP);
        int indexOfWPA2_PSK = 4;
        //从WifiConfiguration.KeyMgmt数组中查找WPA2_PSK的值
        for int i = 0; i < WifiConfiguration.KeyMgmt.strings.length; i++)
        {
            ifWifiConfiguration.KeyMgmt.strings[i].equals"WPA2_PSK"))
            {
                indexOfWPA2_PSK = i;
                break;
            }
        }
        //WifiConfiguration.KeyMgmt.WPA_PSK
        config.allowedKeyManagement.setindexOfWPA2_PSK);
        config.allowedPairwiseCiphers
                .setWifiConfiguration.PairwiseCipher.TKIP);
        config.allowedGroupCiphers.setWifiConfiguration.GroupCipher.CCMP);
        config.allowedPairwiseCiphers
                .setWifiConfiguration.PairwiseCipher.CCMP);
        config.status = WifiConfiguration.Status.ENABLED;
        //通过反射调用设置热点
        try {
            Method method = mWifManager.getClass).getMethod
                    "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
            boolean enable = Boolean) method.invokemWifManager, config, true);

            if enable) {
                Log.e"WiFiAP", "热点已开启 SSID:" + ssid + " Password:"+password);
            } else {
                Log.e"WiFiAP", "创建热点失败");
            }
        } catch Exception e) {
            e.printStackTrace);
            Log.e"WiFiAP", "创建热点失败"+e);
        }

    }

    /**
     * 关闭WiFi热点的方法
     * @param context 外部activity的上下文
     */
    public void closeWiFiAPContext context){
        mWifManager = WifiManager)context.getApplicationContext).getSystemServiceContext.WIFI_SERVICE);
        if mWifManager == null){
            Log.e"closeWiFiAP", "Error: mWifManager is null");
            return;
        }
        try {
            Method method = mWifManager.getClass).getMethod"getWifiApConfiguration");
            method.setAccessibletrue);
            WifiConfiguration config = WifiConfiguration) method.invokemWifManager);
            Method method2 = mWifManager.getClass).getMethod"setWifiApEnabled", WifiConfiguration.class, boolean.class);
            method2.invokemWifManager, config, false);
            //mText.setText"wifi热点关闭");
        } catch NoSuchMethodException e) {
            e.printStackTrace);
        } catch IllegalArgumentException e) {
            e.printStackTrace);
        } catch IllegalAccessException e) {
            e.printStackTrace);
        } catch InvocationTargetException e) {
            e.printStackTrace);
        }

    }
}

 end

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注