Android 连接wifi 检测是否需要portal 认证

前言

最近在做一个新需求,就是针对开机欢迎引导页,当连接如星巴克,KFC,地铁上等公共场所的WIFI时,都需要认证功能,而我要调起这个认证页面呈现给用户,登陆任何网页会跳转到wifi得认证页面,输入账号密码,点击验证,能够验证wifi,并保证手机网络能正常使用。某些手机管家软件在手机连接上CMCC等wifi时,会弹出通知栏提示跳转到webview去进行portal验证。而我由于各种限制原因,并不能自动调用,就需要自己来处理这些功能了,而他们是怎样检测的呢?请往下看~

正文

我们的目标很明确,就是要在wifi连接后,判断wifi是否需要portal验证?如果需要portal验证,那么我们直接启动一个Activity,默认用WebView去加载一个网页,比如:http://XXX.com,服务器就会去检测当前网络是否需要验证(Google会进行一个http的访问,如果返回码为204,就证明手机当前连接的wifi,是不需要进行portal验证的)portal 检测到有新的连接,就会去劫持wifi路由,强制访问wifi的portal验证网页,用户只要完成验证,就可以使用该网络了,实现原理如下:

     /**
     * 验证当前wifi是否需要Portal验证
     * @return
     */  
    private boolean isWifiSetPortal() {
        String mWalledGardenUrl = "http://g.cn/generate_204";
        // 设置请求超时
        int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(mWalledGardenUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setInstanceFollowRedirects(false);
            urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setUseCaches(false);
            urlConnection.getInputStream();
            // 判断返回状态码是否204
            return urlConnection.getResponseCode()!=204;
        } catch (IOException e) {
            //   e.printStackTrace();
            return false;
        } finally {
            if (urlConnection != null) {
                //释放资源
                urlConnection.disconnect();
            }
        }
    }

这块验证一般放在网络改变的广播接受者里面处理的action.equals(ConnectivityManager.CONNECTIVITY_ACTION

把验证方法封装一下就可以判断使用了,很简单吧~~

package woyou.welcome.api;

import android.os.AsyncTask;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Xiho on 11:09
 * MyBlog: xuhaoblog.com
 * GitHub: github.com/git-xuhao
 * Function:
 */
public class CheckWifiLoginTask extends AsyncTask<Integer,Integer,Boolean> {


    private ICheckWifiCallBack mCallBack;


    public CheckWifiLoginTask (ICheckWifiCallBack mCallBack){
        super();
        this.mCallBack=mCallBack;
    }


    @Override
    protected Boolean doInBackground(Integer... params) {
        return isWifiSetPortal();
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if (mCallBack != null) {
            mCallBack.portalNetWork(result);
        }
    }

    /**
     * 验证当前wifi是否需要Portal验证
     * @return
     */
    private boolean isWifiSetPortal() {
        String mWalledGardenUrl = "http://g.cn/generate_204";
        // 设置请求超时
        int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(mWalledGardenUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setInstanceFollowRedirects(false);
            urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS);
            urlConnection.setUseCaches(false);
            urlConnection.getInputStream();
            // 判断返回状态码是否是204
            return urlConnection.getResponseCode()!=204;
        } catch (IOException e) {
            //   e.printStackTrace();
            return false;
        } finally {
            if (urlConnection != null) {
                //释放资源
                urlConnection.disconnect();
            }
        }
    }

    /**
     * 检测Wifi 是否需要portal 认证
     * @param callBack
     */
    public static void checkWifi(ICheckWifiCallBack callBack){
        new CheckWifiLoginTask(callBack).execute();
    }

    public interface ICheckWifiCallBack{
        void portalNetWork(boolean isLogin);
    }

}

在广播接收里判断网络是否需要portal认证:


    /** * 接受网络改变的广播  */
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context mContext, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                //.....省略逻辑
                portalWifi();
            } 
        }
    };

/** wifi 认证 检测 **/
    private void portalWifi() {
        CheckWifiLoginTask.checkWifi(new CheckWifiLoginTask.ICheckWifiCallBack() {
            @Override
            public void portalNetWork(boolean isLogin) {
                //不需要wifi认证
                if(!isLogin){
                   //TODO... 
                }else {
                   //TODO...
                }
            }
        });
    }

实现原理很简单吧~

你可能感兴趣的:(【Android,进阶】)