• 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().getSystemService(Context.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.e(TAG, "WiFi已经启用");
        }

    判断WiFi是否开启

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

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

    开启或者关闭WiFi

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

    mWifiManager.setWifiEnabled(true); //false为关闭

     搜索WiFi与获取WiFi设备列表

    private void scan(){
            mWifiManager.startScan(); //搜索WiFi,在这个代码的注释里有说明搜索过程是异步的
            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    List<ScanResult> list =  mWifiManager.getScanResults(); //获取WiFi列表
                    for (ScanResult scanResult : list){
                        Log.e(TAG, "==================================");
                        Log.e(TAG, "scan: wifi 名称="+scanResult.SSID);
                        Log.e(TAG, "scan: wifi WiFi地址="+scanResult.BSSID);
                        Log.e(TAG, "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,添加到以配置的网络列表里addNetwork(wifiConfiguration);

    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.e(TAG, "list 长度="+list.size());
            for (ScanResult scanResult : list){
                if (scanResult.SSID.equals("My_5g")){ //找到我们需要的WiFi
                    connectionWifi(scanResult.SSID,"winteam0901", scanResult.capabilities); //连接它
                }
    
            }
        }
    
        /**
         * 连接WiFi的方法
         * @param ssid wifi名称
         * @param password WiFi密码
         * @param capabilities 加密方式
         */
        public void connectionWifi(String 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.set(WifiConfiguration.KeyMgmt.NONE);
                wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
    
            } else if (capabilities.contains("OPEN")) {
                wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
    
            }
            mWifiManager.addNetwork(wifiConfiguration);
            List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
            for (WifiConfiguration item : wifiConfigurationList) {
                if (item.SSID == null) {
                    continue;
                }
                if (item.SSID.equals(ssid)) {
                    mWifiManager.disconnect(); //断开连接
                    mWifiManager.enableNetwork(item.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.updateNetwork(item);  但是请注意这个WiFi必须是已经保存配置的WiFi

      /**
         * 更新WiFi
         */
        public void undateWifi(String 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.updateNetwork(item);
                    if (id == -1) { //id如果等于 -1 就说明更新失败了
                        return;
                    }
                    mWifiManager.enableNetwork(id, true); //启用连接WiFi
                    mWifiManager.reconnect();
                }
            }
        }

    移除指定WiFi

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

      /** 
         * 移除这个app保存的WiFi
         *
         * @param ssid
         */
        public void removeWifi(String ssid) {
            mWifiManager.startScan();
            List<WifiConfiguration> wifiConfigurationList = mWifiManager.getConfiguredNetworks();
            for (WifiConfiguration item : wifiConfigurationList) {
                if (item.SSID.equals(""" + ssid + """)) {
                    mWifiManager.disconnect();
                    mWifiManager.removeNetwork(item.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.e(TAG, "getData: 当前未连接WiFi");
            }

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

    /**
         * 移除引号
         *
         * @param content
         * @return
         */
        public String removeQuotationMarks(String content) {
            content = content.substring(1, content.length() - 1);
            return content;
    
        }
    
        /**
         * 添加引号
         *
         * @param content
         * @return
         */
        public String addQuotationMarks(String 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 formatLevel(int 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 getStringId(int idString) {
            StringBuffer sb = new StringBuffer();
            int b = (idString >> 0) & 0xff;
            sb.append(b + ".");
            b = (idString >> 8) & 0xff;
            sb.append(b + ".");
            b = (idString >> 16) & 0xff;
            sb.append(b + ".");
            b = (idString >> 24) & 0xff;
            sb.append(b);
            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();
            registerReceiver(mWiFiChangeReceiver,mIntentFilter);

    接收广播处理

    class WiFiChangeReceiver extends BroadcastReceiver{
    
            @Override
            public void onReceive(Context context, Intent intent) {
    
                if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                    int switchState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);//得到WiFi开关状态值
                    switch (switchState) {
                        case WifiManager.WIFI_STATE_DISABLED://WiFi已关闭
                            WiFIStateData data1 = new WiFIStateData();
                            data1.time = mDf.format(System.currentTimeMillis());
                            data1.state = "WiFi关闭";
                            mDao.insert(data1);
                            EventBus.getDefault().post(msgData);
                            Log.e(TAG, "WiFi关闭");
                            break;
                        case WifiManager.WIFI_STATE_DISABLING://WiFi关闭中
                            Log.e(TAG, "WiFi关闭中");
                            break;
                        case WifiManager.WIFI_STATE_ENABLED://WiFi已开启
                            WiFIStateData data2 = new WiFIStateData();
                            data2.time = mDf.format(System.currentTimeMillis());
                            data2.state = "WiFi开启";
                            mDao.insert(data2);
                            EventBus.getDefault().post(msgData);
                            Log.e(TAG, "WiFi开启");
                            break;
                        case WifiManager.WIFI_STATE_ENABLING://WiFi开启中
                            Log.e(TAG, "WiFi开启中");
                            break;
                        case WifiManager.WIFI_STATE_UNKNOWN://WiFi状态未知
                            WiFIStateData data3 = new WiFIStateData();
                            data3.time = mDf.format(System.currentTimeMillis());
                            data3.state = "WiFi状态未知";
                            mDao.insert(data3);
                            EventBus.getDefault().post(msgData);
                            Log.e(TAG, "WiFi状态未知");
                            break;
                        default:
                            break;
                    }
                }
    
                    if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ //网络状态改变行为
                        Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.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.format(System.currentTimeMillis());
                                    data4.state = "已经连接";
                                    mDao.insert(data4);
                                    EventBus.getDefault().post(msgData);
                                    Log.e(TAG, "已经连接");
                                    break;
                                case DISCONNECTED:
                                    if (mDisconnectState){
                                        mDisconnectState = false;
                                        WiFIStateData data5 = new WiFIStateData();
                                        data5.time = mDf.format(System.currentTimeMillis());
                                        data5.state = "已经断开";
                                        mDao.insert(data5);
                                        EventBus.getDefault().post(msgData);
                                        Log.e(TAG, "已经断开");
                                    }
                                    break;
                                case IDLE:
    
                                    WiFIStateData data6 = new WiFIStateData();
                                    data6.time = mDf.format(System.currentTimeMillis());
                                    data6.state = "空闲中";
                                    mDao.insert(data6);
                                    EventBus.getDefault().post(msgData);
                                    Log.e(TAG, "空闲中");
    
                                    break;
                                case AUTHENTICATING:
    
                                    WiFIStateData data7 = new WiFIStateData();
                                    data7.time = mDf.format(System.currentTimeMillis());
                                    data7.state = "认证中";
                                    mDao.insert(data7);
                                    EventBus.getDefault().post(msgData);
                                    Log.e(TAG, "认证中");
    
                                    break;
                                case BLOCKED:
    
                                    WiFIStateData data8 = new WiFIStateData();
                                    data8.time = mDf.format(System.currentTimeMillis());
                                    data8.state = "认证失败";
                                    mDao.insert(data8);
                                    EventBus.getDefault().post(msgData);
                                    Log.e(TAG, "认证失败");
    
                                    break;
                                case CAPTIVE_PORTAL_CHECK:
    
                                    WiFIStateData data9 = new WiFIStateData();
                                    data9.time = mDf.format(System.currentTimeMillis());
                                    data9.state = "连接检查";
                                    mDao.insert(data9);
                                    EventBus.getDefault().post(msgData);
                                    Log.e(TAG, "连接检查");
    
                                    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 setConnectionWifi(ConnectionWifi connectionWifi) {
            this.connectionWifi = connectionWifi;
        }
    
        public List<ConfigWifi> getConfigWifiList() {
            return configWifiList;
        }
    
        public void setConfigWifiList(List<ConfigWifi> configWifiList) {
            this.configWifiList = configWifiList;
        }
    
        public List<OtherWifi> getOtherWifiList() {
            return otherWifiList;
        }
    
        public void setOtherWifiList(List<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 setSsid(String ssid) {
                this.ssid = ssid;
            }
    
            public Integer getLevel() {
                return level;
            }
    
            public void setLevel(Integer level) {
                this.level = level;
            }
    
            public Integer getIpAddress() {
                return ipAddress;
            }
    
            public void setIpAddress(Integer ipAddress) {
                this.ipAddress = ipAddress;
            }
    
            public Integer getFrequency() {
                return frequency;
            }
    
            public void setFrequency(Integer 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 setSsid(String ssid) {
                this.ssid = ssid;
            }
    
            public Integer getLevel() {
                return level;
            }
    
            public void setLevel(Integer level) {
                this.level = level;
            }
    
            public Integer getState() {
                return state;
            }
    
            public void setState(Integer state) {
                this.state = state;
            }
    
            public String getCapabilities() {
                return capabilities;
            }
    
            public void setCapabilities(String capabilities) {
                this.capabilities = capabilities;
            }
        }
    
        public class OtherWifi{
            private String ssid;
            private Integer level; //信号强度
            private String capabilities;//安全形式
    
            public String getSsid() {
                return ssid;
            }
    
            public void setSsid(String ssid) {
                this.ssid = ssid;
            }
    
            public Integer getLevel() {
                return level;
            }
    
            public void setLevel(Integer level) {
                this.level = level;
            }
    
            public String getCapabilities() {
                return capabilities;
            }
    
            public void setCapabilities(String 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.addAll(mWifiManager.getScanResults());
            configurationList.addAll(mWifiManager.getConfiguredNetworks());
    
    
            List<WifiDataBean.ConfigWifi> configWifiList = new ArrayList<>();
            List<WifiDataBean.OtherWifi> otherWifiList = new ArrayList<>();
    
            /*
                处理当前正在连接中的WiFi
             */
            if (wifiInfo.getIpAddress() == 0) {
                wifiDataBean.setConnectionWifi(null);
            } else {
                WifiDataBean.ConnectionWifi connectionWifi = wifiDataBean.new ConnectionWifi();
                connectionWifi.setSsid(wifiInfo.getSSID());
                connectionWifi.setLevel(wifiInfo.getRssi());
                connectionWifi.setIpAddress(wifiInfo.getIpAddress());
                connectionWifi.setFrequency(wifiInfo.getFrequency());
                wifiDataBean.setConnectionWifi(connectionWifi);
            }
    
            /*
                处理已经配置过的WiFi
             */
            if (configurationList.isEmpty()) {
                wifiDataBean.setConfigWifiList(configWifiList);
    
            } else {
                for (int i = 0; i < configurationList.size(); i++) { //除去null的WiFi
                    WifiConfiguration configuration = configurationList.get(i);
                    if (configuration.SSID == null) {
                        configurationList.remove(configuration);
                    }
                }
    
                if (wifiDataBean.getConnectionWifi() != null) {
                    for (int i = 0; i < configurationList.size(); i++) { //去除正在连接的WiFi item
                        WifiConfiguration configuration = configurationList.get(i);
                        if (configuration.SSID.equals(wifiDataBean.getConnectionWifi().getSsid())) {
                            configurationList.remove(configuration);
                        }
                    }
                }
    
                for (int i = 0; i < configurationList.size(); i++) { //除去重复的WiFi
                    WifiConfiguration configuration = configurationList.get(i);
                    for (int j = i + 1; j < configWifiList.size(); j++) {
                        WifiConfiguration item = configurationList.get(j);
                        if (configuration.SSID.equals(item.SSID)) {
                            configurationList.remove(item);
                        }
    
                    }
                }
    
                for (int i = 0; i < configurationList.size(); i++) { //添加配置过的WiFi数据
                    WifiConfiguration configuration = configurationList.get(i);
                    WifiDataBean.ConfigWifi configWifi = wifiDataBean.new ConfigWifi();
                    configWifi.setSsid(configuration.SSID);
                    configWifi.setState(configuration.status);
                    for (int j = 0; j < scanResultList.size(); j++) {
                        ScanResult scanResult = scanResultList.get(j);
                        if (removeQuotationMarks(configuration.SSID).equals(scanResult.SSID)) {
                            configWifi.setLevel(scanResult.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.add(configWifi);
                }
                wifiDataBean.setConfigWifiList(configWifiList);
            }
    
            /*
                设置其他WiFi
             */
            if (scanResultList.isEmpty()) {
                wifiDataBean.setOtherWifiList(otherWifiList);
    
            } else {
                for (int i = 0; i < scanResultList.size(); i++) { //去除null
                    ScanResult scanResult = scanResultList.get(i);
                    if (scanResult.SSID == null) {
                        scanResultList.remove(scanResult);
                    }
                }
    
                if (wifiDataBean.getConnectionWifi() != null){
                    for (int i = 0; i < scanResultList.size(); i++) { //去除已连接的
                        ScanResult scanResult = scanResultList.get(i);
                        if (scanResult.SSID.equals(removeQuotationMarks(wifiDataBean.getConnectionWifi().getSsid()))) {
                            scanResultList.remove(scanResult);
                        }
                    }
                }
    
                for (int i = 0; i < scanResultList.size(); i++) { //去除已配置的
                    ScanResult scanResult = scanResultList.get(i);
                    for (int j = 0; j < configWifiList.size(); j++) {
                        WifiDataBean.ConfigWifi configWifi = configWifiList.get(j);
                        if (removeQuotationMarks(configWifi.getSsid()).equals(scanResult.SSID)) {
                            scanResultList.remove(scanResult);
                        }
                    }
                }
    
                for (int i = 0; i < scanResultList.size(); i++) { //去除重复的
                    ScanResult scanResult = scanResultList.get(i);
                    for (int j = i + 1; j < scanResultList.size(); j++) {
                        ScanResult item = scanResultList.get(j);
                        if (scanResult.SSID.equals(item.SSID)) {
                            scanResultList.remove(item);
                        }
                    }
                }
    
                for (int i = 0; i < scanResultList.size(); i++) {
                    ScanResult scanResult = scanResultList.get(i);
                    WifiDataBean.OtherWifi otherWifi = wifiDataBean.new OtherWifi();
                    otherWifi.setSsid(scanResult.SSID);
                    otherWifi.setLevel(scanResult.level);
                    otherWifi.setCapabilities(scanResult.capabilities);
                    otherWifiList.add(otherWifi);
                }
                wifiDataBean.setOtherWifiList(otherWifiList);
            }
            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 setPermissions(Context context){
            Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
    
        }
    
        /**
         * 打开热点并且创建WiFi热点的方法
         * @param context 外部上下文
         * @param ssid 要创建WiFi热点的账号名称
         * @param password 要创建WiFi热点的密码
         * 注意,此方法直接使用WPA2_PSK 的安全策略创建WiFi热点,低版本的Android系统如果需要使用请切换。
         */
        @SuppressLint("MissingPermission")
        public void openWiFiAP(Context context, String ssid, String password){
    
            mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    
            if (mWifManager.isWifiEnabled()) {
                //如果wifi处于打开状态,则关闭wifi,
                mWifManager.setWifiEnabled(false);
            }
            WifiConfiguration config = new WifiConfiguration();
            config.SSID = ssid;
            config.preSharedKey = password;
            config.hiddenSSID = false;//是否隐藏热点true=隐藏
            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            int indexOfWPA2_PSK = 4;
            //从WifiConfiguration.KeyMgmt数组中查找WPA2_PSK的值
            for (int i = 0; i < WifiConfiguration.KeyMgmt.strings.length; i++)
            {
                if(WifiConfiguration.KeyMgmt.strings[i].equals("WPA2_PSK"))
                {
                    indexOfWPA2_PSK = i;
                    break;
                }
            }
            //WifiConfiguration.KeyMgmt.WPA_PSK
            config.allowedKeyManagement.set(indexOfWPA2_PSK);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
            //通过反射调用设置热点
            try {
                Method method = mWifManager.getClass().getMethod(
                        "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
                boolean enable = (Boolean) method.invoke(mWifManager, 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 closeWiFiAP(Context context){
            mWifManager = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            if( mWifManager == null){
                Log.e("closeWiFiAP", "Error: mWifManager is null");
                return;
            }
            try {
                Method method = mWifManager.getClass().getMethod("getWifiApConfiguration");
                method.setAccessible(true);
                WifiConfiguration config = (WifiConfiguration) method.invoke(mWifManager);
                Method method2 = mWifManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
                method2.invoke(mWifManager, 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

  • 相关阅读:
    第六周
    第五周
    第四周
    第二周学习记录
    实验一 Linux初步认识
    java实验四
    java实验三
    为什么无密码认证能够有效
    关于父元素,子元素,同级元素的DOM操作技巧
    高效设计构建软件的十三条建议
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/9708586.html
Copyright © 2020-2023  润新知