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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM