需求
在测试过程中也发现应用下载的文件大小都是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);
}
}