前言
最近在做一个新需求,就是针对开机欢迎引导页,当连接如星巴克,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...
}
}
});
}
实现原理很简单吧~