FaceBook like 按钮在 Android WebView中的Bug的解决
FaceBook like 按钮在 Android WebView中的Bug
(To fix the Bug about FaceBook Like Button on Android WebView)
writen by Tony@Tokyo
1. Bug的描述
在Web页面上,可以如下添加上FaceBook的Like按钮,即时分享
<head> <title>FB Test</title> <script src="http://connect.facebook.net/en_US/all.js#xfbml=1" type="text/javascript"></script> </head> <body> <fb:like href="http://www.stackoverflow.com" layout="button_count" show_faces="false" width="450" font=""></fb:like> </body>
在PC的浏览器上和手机的浏览器上,点击Like按钮的时候,都会弹出一个facebook的login按钮,成功经过login以后,会跳回本页面,显示fb关注+1
但是在Android App中,在webview中加载这个页面之后,点击按钮,会跳出本app,打开一个新的浏览器窗口,显示facebooklogin画面。
login成功以后,会跳到一个空白画面(blank page),画面的url如下
https://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php?plugin_secure=1&social_plugin=like&external_page_url=https%3A%2F%2Fthesiteyourwanttoredirect.com%2Fdetail%2F%3Fproduct_id%3D214#_=_
2. Bug的分析
在程序里debug,facebook like按钮点击以后发生的动作
首先打开
https://www.facebook.com/connect/uiserver.php?social_plugin=like&method=opt.inlike&display=popup&secure=true&app_id=127760087237610&protocol=https%3A&external_page_url=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D319&nux=true&referer=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D319
facebook发现没有login,则被重定向到
https://www.facebook.com/login.php?skip_api_login=1&display=popup&nux=1&referer=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D319&social_plugin=like&external_page_url=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D319&next=https%3A%2F%2Fwww.facebook.com%2Fconnect%2Fuiserver.php%3Fmethod%3Dopt.inlike%26app_id%3D127760087237610%26display%3Dpopup%26nux%3D1%26referer%3Dhttps%253A%252F%252Fthesiteyourwanttoredirect%252Fdetail%252F%253Fproduct_id%253D319%26social_plugin%3Dlike%26secure%3Dtrue%26protocol%3Dhttps%253A%26external_page_url%3Dhttps%253A%252F%252Fthesiteyourwanttoredirect%252Fdetail%252F%253Fproduct_id%253D319%26from_login%3D1%26client_id%3D127760087237610&rcount=1
login成功以后,被重定向到以下,进行分享动作
https://www.facebook.com/connect/uiserver.php?method=opt.inlike&app_id=127760087237610&display=popup&nux=1&referer=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D2&social_plugin=like&secure=true&protocol=https%3A&external_page_url=https%3A%2F%2Fthesiteyourwanttoredirect%2Fdetail%2F%3Fproduct_id%3D2&from_login=1&client_id=127760087237610&refsrc=http%3A%2F%2Fwww.facebook.com%2Flogin.php&refid=9&_rdr
在这边,根据WebKit的内核,会有不同的操作,
有些内核会跳转到以下,试图关闭popup画面
https://www.facebook.com/plugins/close_popup.php
有些会发现无法执行关闭popup的动作,直接跳到以下白画面
https://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php
这个的原因是因为:
a. facebook的login画面,是跳离app的webview,打开浏览器窗口进行。因此login之后留下的cookie,App中的webview完全无法共享。
b. App中的webview,无法模拟出js popup的效果,打断了facebook 预想的事物链
3. Bug的对策:
a. 在app中自定义webview,截获facebook的请求,hock the problem,我采取的就是这种方法
首先自定义一个WebViewClient,在里面截获住url的跳转,发现是facebook的话,就在webview内部迁移
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) {if (url.startsWith("https://www.facebook.com")||(url.startsWith("http://m.facebook.com/login.php"))) {view.loadUrl(url);return true;}}
接下来,在WebViewClient的onPageFinished中截获WebView成功显示之后的url,如果发现是aim url, 则跳过去. hock the url
@Override public void onPageFinished(WebView view, String url) { String redirectURL = new String(); if(url.startsWith("https://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php")){ redirectURL = getRedirectURL(url, 1); view.loadUrl(redirectURL); return; } else if (url.startsWith("https://www.facebook.com/plugins/close_popup.php")) { redirectURL = getRedirectURL(url, 2); view.loadUrl(redirectURL); return; } }
getRedirectURL是根据业务需要,从facebook的重定向url中找出自己的原页面url,这里就不讲了。
b. 让WebView支持popup window (我没试验成功)
WebSettings settings = webView.getSettings();settings.setJavaScriptEnabled(true);settings.setSupportZoom(false);settings.setJavaScriptCanOpenWindowsAutomatically(true);settings.setSupportMultipleWindows(true);
webView.setWebChromeClient(new MyWebChromeClient());webView.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_OVERLAY);webView.loadUrl(ASSET_URL);
final class MyWebChromeClient extends WebChromeClient {// Add new webview in same window@Overridepublic boolean onCreateWindow(WebView view, boolean dialog,boolean userGesture, Message resultMsg) {childView = new WebView(DeviceTestActivity.this);childView.getSettings().setJavaScriptEnabled(true);childView.setWebChromeClient(this);childView.setWebViewClient(new WebViewClient());childView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));contentContainer.addView(childView);WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;transport.setWebView(childView);resultMsg.sendToTarget();return true;}// remove new added webview whenever onCloseWindow gets called// for new webview.@Overridepublic void onCloseWindow(WebView window) {// webView.removeViewAt(webView.getChildCount()-1);childView.setVisibility(View.GONE);}}
c. 用dialog代替facebook的popup login window (我试过了,但是dialog里依然出现blank page)
参考文献:
http://stackoverflow.com/questions/5108088/android-webview-for-facebook-like-button
#以上#
更多相关文章
- Android TextView限定行数最大值,点击按钮显示所有内容
- android 按钮的文字显示不全
- Android中开关按钮IOS效果的实现
- android点击按钮发出声音
- android按钮main.xm_基础篇
- Android 控件之一:Button 按钮
- Android按钮的五种点击监听事件处理
- Android 键盘挤压 按钮