使用AndServer實現類似連接wifi需要portal認證全過程

我的使用場景:新買的盒子無屏如何通過手機讓盒子連上wifi

1、首先依賴AndServer,添加權限,開啓服務

github地址-https://github.com/yanzhenjie/AndServer

implementation 'com.yanzhenjie:andserver:1.0.2'//該版本不是最新版本

<!--wifi 網絡權限 -->
    <uses-permission android:name="android.permission.CHANGE_NETWORKE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
//創建並開啓服務
private void createWebServer(){
        AssetManager mAssetManager = getAssets();
        //如果xx.html在assets下填""即可,如果在assets子目錄下填子目錄的文件名
        WebSite wesite = new AssetsWebsite(mAssetManager, path);
        AndServer andServer = new AndServer.Build()
                .port(8080) // 默認是8080,Android平臺允許的端口號都可以。
                .timeout(10 * 1000) // 默認10 * 1000毫秒。
                .website(wesite)
                .registerHandler("wifi", new RequestWifiHandler())
                .registerHandler("login", new RequestLoginHandler())
                .listener(mListener)
                .build();
        Server mServer = andServer.createServer();
        mServer.start();
 }
//服務狀態監聽
private Server.Listener mListener = new Server.Listener() {
        @Override
        public void onStarted() {
            // 服務器啓動成功.
            LogUtils.d("服務器啓動成功");
        }

        @Override
        public void onStopped() {
            // 服務器停止了,一般是開發者調用server.stop()纔會停止。
            LogUtils.d("服務器停止了");
        }

        @Override
        public void onError(Exception e) {
            // 服務器啓動發生錯誤,一般是端口被佔用。
            LogUtils.d("服務器啓動發生錯誤");
        }
    };

2、創建並開啓熱點

private void createWifiHot(String name, String password) {
        WifiManager mWifiManager = (WifiManager) LemonConfig.getApplicationContext().getSystemService(WIFI_SERVICE);
        try {
            //wifi和熱點不能同時打開,所以先判斷wifi是否打開,打開則關閉
            if (mWifiManager.isWifiEnabled()) {
                mWifiManager.setWifiEnabled(false);
            }
            //java反射機制得到Method
            Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class, boolean.class);
            //配置熱點信息
            WifiConfiguration config = new WifiConfiguration();
            config.SSID = name;
            config.preSharedKey = password;
            config.hiddenSSID = true;
            config.status = WifiConfiguration.Status.ENABLED;
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            /*****如果連接熱點需要密碼,則解開註釋,將config.allowedKeyManagement.set(0);註釋掉****/
//            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;
//                }
//            }
            config.allowedKeyManagement.set(0);
            //通過java反射調用WifiManager的setWifiApEnabled方法
            method.invoke(mWifiManager, config, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3、手機連上熱點,這樣開啓服務的設備與連上熱點的手機就形成了一個局域網,通過http://ip:port/xxx.html就可以訪問我們寫好的html頁面

4、html要提交給本地服務器通過第一步創建服務註冊名來進行訪問

在這裏插入圖片描述
在這裏插入圖片描述

5、在RequestWifiHandler類中接受html頁面提交過來的信息,得到wifi名稱和wifi密碼進行連接

public class RequestWifiHandler implements RequestHandler {

    private WifiManager mWifiManager;

    @Override
    public void handle(HttpRequest req, HttpResponse res, HttpContext con) {
        Map<String, String> params = null;
        try {
            params = HttpRequestParser.parse(req);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 在這裏得到html頁面提交過來的參數,字段與html的name屬性值對應上
        String ssid = params.get("username");
        String pwd = params.get("password");
        LogUtils.d( "wifi!");
        openWifi(ssid,pwd,res);
    }
	//關閉熱點,打開wifi
    private void openWifi(String userName, String password,HttpResponse res) {
        mWifiManager = (WifiManager) LemonConfig.getApplicationContext().getSystemService(WIFI_SERVICE);
        closeWifiHot();
        // 調用函數打開/關閉WiFi,status爲boolean變量true/false
        if (!mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(true);
        }
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();

        // 指定對應的SSID
        config.SSID = "\"" + userName + "\"";

        config.preSharedKey = "\"" + password + "\"";
        config.hiddenSSID = true;
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        config.status = WifiConfiguration.Status.ENABLED;

        int netId = mWifiManager.addNetwork(config);

        // 這個方法的第一個參數是需要連接wifi網絡的networkId,第二個參數是指連接當前wifi網絡是否需要斷開其他網絡
        boolean isConnection=mWifiManager.enableNetwork(netId, true);
        if (isConnection) {
//            ProcessBuilder.Redirect.
            StringEntity stringEntity = null;
            try {
                stringEntity = new StringEntity("連接成功", "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            res.setEntity(stringEntity);
        }else {
        //它不能夠立馬連接上,所以要從頭再走一遍
            openWifi(userName, password, res);
        }
    }
    //關閉熱點
    public void closeWifiHot() {
        try {
            Method method = mWifiManager.getClass().getMethod("setWifiApEnabled",WifiConfiguration.class, boolean.class);
            method.invoke(mWifiManager, null, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章