搜索
您的当前位置:首页正文

wifi portal 检测(wifi连接后需要登陆验证的网络判

来源:二三娱乐

需求

在测试过程中也发现应用下载的文件大小都是16B,直觉告诉我这是网络出了问题,但是又能下载说明请求本身是成功的,最后发现是测试时所处的网络在连接后还需要登陆的网络,所下载的内容是一个登陆页面html代码。由此引出了今天我们要讨论的问题,wifi portal 登陆检测。

概念

那什么是portal认证?
概念我就不讲了,举个栗子:你去交通银行办理业务在排队的时候发现他家有免费的wifi,你链接上,打开浏览器,提示你需要输入手机号和验证码,你按照指示输入内容点击“我要上网”。然后你就可以链接上网络了。这个过程中“你已经接入网络,网络提示你输入手机号和验证码已验证你的身份”这个过程就是portal认证。

试过的错误方式

这个方式尽管来头不小,可是不管用(也或许我使用的方式不对)

so i save it as img for you

笔者认为,上面解释及下面的栗子主要思想就是:你发送一个请求,请求中包含了你请求地址的host如果请求没有被重定向到登陆界面,那么response中host的地址依然还是原来的host,否则他就不应该是原来的host。

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            if (url.getHost().equals(urlConnection.getURL().getHost())) {
                // we were redirected! kick the user out to the browser to sign on?
            }
        ......
        } finally {
            urlConnection.disconnect();
        }

我要讲的方法

其实想想这个功能对于手机系统是个蛮重要的,难道Android没有实现么,我不用说你也知道答案了。确实有,但是由于Google服务器在墙外,导致了这个功能不能用了。
程序员搜索要用Google
程序员搜索要用Google
程序员搜索要用Google
我在百度搜索了半天的解决方案,始终是没有头绪,只好Google了下,分分钟找到了这个方法。(又一次深深的教育了我:程序员用Google)

为了避免大家一头雾水,我先说说他的原理:

核心方法

 private boolean isWifiSetPortal() {  
        // 商定的请求链接
        final String mWalledGardenUrl =   
        // 设置请求超时
        final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;  
  
        HttpURLConnection urlConnection = null;  
        try {  
            URL url = new URL(mWalledGardenUrl);  
            urlConnection = (HttpURLConnection) url.openConnection();  
            // 是否应该自动执行 http 重定向(响应代码为 3xx 的请求)。
            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) {  
            return false;  
        } finally {  
            if (urlConnection != null) {  
                // 记得释放资源
                urlConnection.disconnect();  
            }  
        }  
    }  

下面是我写好的代码,但是我还没有应用于生产环境\我还没有应用于生产环境\我还没有应用于生产环境,所以不保证在真实应用下的效果。


import java.io.IOException;
import 
import 

import android.os.AsyncTask;
/**
 * 检测wifi是否需要登陆
 * @author like
 * 
 * 使用方式:
 * NetNeedLoginCheckUtil.needLoginNetworkCheck(new NeedLoginCallBack() {
 *  @Override
 *  public void needLogin(boolean needLogin) {
 *     if (needLogin) {
 *          wifi 需要登陆
 *     }
 *  }
 * });
 * 
 * 实现方式来至Android4.0.1AOSP code
 * @link 
 *
 */
public class NetNeedLoginCheckUtil extends AsyncTask<Integer, Integer, Boolean>{

    NeedLoginCallBack callBack;

    public NetNeedLoginCheckUtil(NeedLoginCallBack callBack) {
        super();
        this.callBack = callBack;
    }

    @Override
    protected Boolean doInBackground(Integer... params) {
        return isWifiSetPortal();
    }
    
    @Override
    protected void onPostExecute(Boolean result) {
        if (callBack != null) {
            callBack.needLogin(result);
        }
    }

    private boolean isWifiSetPortal() {  
        final String mWalledGardenUrl =   
        final 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();  
            return urlConnection.getResponseCode() != 204;  
        } catch (IOException e) {  
            return false;  
        } finally {  
            if (urlConnection != null) {  
                urlConnection.disconnect();  
            }  
        }  
    }  
    
    public static void needLoginNetworkCheck(NeedLoginCallBack callBack) {
        new NetNeedLoginCheckUtil(callBack).execute();
    }
    
    public interface NeedLoginCallBack{
        void needLogin(boolean needLogin);
    }
}
Top