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
#以上#

更多相关文章

  1. Android TextView限定行数最大值,点击按钮显示所有内容
  2. android 按钮的文字显示不全
  3. Android中开关按钮IOS效果的实现
  4. android点击按钮发出声音
  5. android按钮main.xm_基础篇
  6. Android 控件之一:Button 按钮
  7. Android按钮的五种点击监听事件处理
  8. Android 键盘挤压 按钮

随机推荐

  1. Android调用测试
  2. android animation
  3. Android上的OpenGL ES 使用错误 解决
  4. Android中RatingBar的自定义总结
  5. ubuntu环境下我的第一个android apk (201
  6. android 老是弹出 "Copy" did not comple
  7. ListView.setOnItemClickListener、setOn
  8. Android(安卓)入门到精通 (界面编程#2-Men
  9. android app 添加logo
  10. CCRenderTexture 从后台进入前台变黑的处