最近有个项目需要用到第三方身份验证,进行用户登录,考虑到同时兼容多个第三方平台(如网易,新浪,腾讯等)的验证,而且要达到最大可能的跨平台(同时支持网页端和手机端),最终确定采取使用网页方式进行第三方的身份验证,以便于在线维护升级。
既然是在线系统,手机端就是访问该网点就是了。Android上提供了强大的WebView控件,利用这一工具,我们可以拦截各种由后台发起的页面跳转,也可以响应页面的JS脚本操作等等。以下是记录了一些,在项目过程中,遇到的问题的解决记录。
1、重定向URL的拦截:
我们首先了解一下类android.webkit.WebViewClient,WebViewClient是管理WebView加载URL指定页面的周期管理类,下面都是其加载的周期函数,通过继承并重载android.webkit.WebViewClient的两个方法shouldOverrideUrlLoading和onPageStarted,就可以实现拦截指定的重定向URL。
//begin load url at here
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (url.startsWith(BindURL)) {
Result result = parseTargetURL(url);
handleResult(result);
return;
}
}
//redirect when page loading, go here
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(BindURL)) {
Result result = parseTargetURL(url);
handleResult(result);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
// when load complete , go here
public void onPageFinished(WebView view, String url) {
handler.sendEmptyMessage(App.WebPageLoadOver);
}
//load page fail, go here
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
handler.sendEmptyMessage(App.WebPageLoadError);
super.onReceivedError(view, errorCode, description, failingUrl);
}
2、响应页面的JS弹窗
要在WebView上响应JS脚本,必须地要有以下的设置代码,
WebSettings setting = webview.getSettings();
setting.setJavaScriptCanOpenWindowsAutomatically(true);
setting.setJavaScriptEnabled(true);
然后得响应其弹窗请求,js代码:Alert.show("这是弹窗..."); 但是我们响应的弹窗十一什么的形式弹出来的?最方便的,当然就是用AlertDialog来装载js弹窗的内容了。ok,剩下要做的,就是拦截js的请求了。
这里我们有android.webkit.WebChromeClient,和WebViewClient管理加载URL不同,WebChromeClient是用来管理相关资源的,js也就是页面的资源之一了。
WebChromeClient也提供了相当丰富健全的回调API,可是在这里,我只有响应JS弹窗的需求,具体见下面的实例,下面一段时重载WebChromeClient的方法:
@Override //call when javascript request a popup window
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result) {
new AlertDialog.Builder(ThirdPartyAuthActivity.this)
.setTitle("网页说:")
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
result.confirm();
//tell js, we handle it's request
}
}).create().show();
return true;
}
});
最后不要忘了把重载的WebChromeClient实例设置到view.setWebChromeClient(new WebChromeClient() {.........});
3、实现网页后退
习惯上网冲浪的人,对网页的后退肯定熟悉得不得了,可是在webview上怎么去实现呢?简单呗,之间按Back键就是了,结果一按,整个装载webview的Activity的退出去了,简单分析,就是返回的动作没有被webview监听到,反而通知到了Activity,那Activity当然也返回上一页了。OK,那思路就简单了,webview主动去监听Back键的动作:
webview.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK &&
webview.canGoBack()) { //表示按返回键时的操作
webview.goBack(); //后退
return true; //已处理
}
}
return false;
}
});