之前写过在Android上判断是否有可用的网络(流量或者wifi),这基本上都够用了。但是有一种portal wifi,虽然判定是可用的,且ping也是能ping通的,但是就是上不了网,因为wifi需要输入动态验证码。在火车站、汽车站、商场之类的地方,portal wifi比较常见。
如果app里面需要处理这种情况,那么可以根据网络请求的返回值来判断,基本上statusCode是300+的都是重定向,一般是重定向到portal wifi的获取验证码页面。
private void isWifiSetPortal() {
// 商定的请求链接
final String mWalledGardenUrl = "xxxx";
// 设置请求超时
final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(mWalledGardenUrl);
urlConnection = (HttpURLConnection) url.openConnection();
StringBuffer resultData = new StringBuffer();
InputStreamReader in = new InputStreamReader(urlConnection.getInputStream());
// 为输出创建BufferedReader
BufferedReader buffer = new BufferedReader(in);
String inputLine = null;
//使用循环来读取获得的数据
while (((inputLine = buffer.readLine()) != null))
{
//我们在每一行后面加上一个"\n"来换行
resultData.append(inputLine+"\n");
}
Log.d("Portal", "resultData="+resultData.toString());
// 判断host是否相同,不相同,则跳转到相应url
if(url.getHost().equals(urlConnection.getURL().getHost())) {
Message message = new Message();
message.what = MSG_SHOW_REQUEST_RESULT;
Bundle bundle = new Bundle();
bundle.putString("result", resultData.toString());
message.setData(bundle);
mHandler.sendMessage(message);
}else {
Intent intent = new Intent(this, WebViewActivity.class);
intent.putExtra("url", urlConnection.getURL().toString());
this.startActivity(intent);
}
} catch (Exception e) {
Log.d("Portal", "urlconnnection,exception = "+e.toString());
e.printStackTrace();
} finally {
if (urlConnection != null) {
// 记得释放资源
urlConnection.disconnect();
}
}
}
用来呈现重定向后的页面的Activity如下,用户进行登录验证操作之后,就可以返回其他页面进行正常的网络交互了。
// WebViewActivity.class
public class WebViewActivity extends AppCompatActivity {
Context mContext;
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
mContext = this.getApplicationContext();
String url = getIntent().getStringExtra("url");
webView = (WebView) findViewById(R.id.webview);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
});
webView.loadUrl(url);
}
}
这里要说明几点,
1.如果要访问的页面里面有JavaScript,那么webview必须支持javascript。portal wifi的验证页面是有JavaScript的。
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
2.如果页面中有链接,希望点击链接继续在当前browser中响应,而不是新开系统的browser进行响应,则必须覆盖WebView的WebViewClient对象。
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return super.shouldOverrideUrlLoading(view, url);
}
});
关于portal wifi的原理,可以看这篇博客