Android WebView for Facebook Like Button

18,716

Solution 1

To get past the blank page you do this:

 webview.setWebViewClient(new LikeWebviewClient(this));

 private class LikeWebviewClient extends WebViewClient {        
    @Override
    public void onPageFinished(WebView view, String url) {
        Log.d(TAG, "onPageFinished url: " +url);
        // Facebook redirects to this url once a user has logged in, this is a blank page so we override this
        // http://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php?............
        if(url.startsWith("http://www.facebook.com/connect/connect_to_external_page_widget_loggedin.php")){
            String redirectUrl = getFacebookLikeUrl();
            view.loadUrl(redirectUrl);
            return;
        }
        super.onPageFinished(view, url);
    }
}

Solution 2

I had the same issue on my android application. The cause of the issue is FB login javascript opens a new page on a new window. Then it tries to close it after login success. Please follow flowing example from my working codes.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".MyActivity" 
android:id="@+id/webview_frame">
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

The Webview of id "webview" is the main view for my content. Below is my activity codes.

public class MyActivity extends Activity {
/* URL saved to be loaded after fb login */
private static final String target_url="http://www.example.com";
private static final String target_url_prefix="www.example.com";
private Context mContext;
private WebView mWebview;
private WebView mWebviewPop;
private FrameLayout mContainer;
private long mLastBackPressTime = 0;
private Toast mToast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_urimalo);
// final View controlsView =
// findViewById(R.id.fullscreen_content_controls);
CookieManager cookieManager = CookieManager.getInstance(); 
cookieManager.setAcceptCookie(true); 
mWebview = (WebView) findViewById(R.id.webview);
//mWebviewPop = (WebView) findViewById(R.id.webviewPop);
mContainer = (FrameLayout) findViewById(R.id.webview_frame);
WebSettings webSettings = mWebview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAppCacheEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);
mWebview.setWebViewClient(new UriWebViewClient());
mWebview.setWebChromeClient(new UriChromeClient());
mWebview.loadUrl(target_url);

mContext=this.getApplicationContext();
}
private class UriWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    String host = Uri.parse(url).getHost();
    //Log.d("shouldOverrideUrlLoading", url);
    if (host.equals(target_url_prefix)) 
    {
        // This is my web site, so do not override; let my WebView load
        // the page
        if(mWebviewPop!=null)
        {
            mWebviewPop.setVisibility(View.GONE);
            mContainer.removeView(mWebviewPop);
            mWebviewPop=null;
        }
        return false;
    }

    if(host.equals("m.facebook.com"))
    {
        return false;
    }
    // Otherwise, the link is not for a page on my site, so launch
    // another Activity that handles URLs
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    startActivity(intent);
    return true;
}

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,
        SslError error) {
    Log.d("onReceivedSslError", "onReceivedSslError");
    //super.onReceivedSslError(view, handler, error);
}
}
class UriChromeClient extends WebChromeClient {

@Override
public boolean onCreateWindow(WebView view, boolean isDialog,
        boolean isUserGesture, Message resultMsg) {
    mWebviewPop = new WebView(mContext);
    mWebviewPop.setVerticalScrollBarEnabled(false);
    mWebviewPop.setHorizontalScrollBarEnabled(false);
    mWebviewPop.setWebViewClient(new UriWebViewClient());
    mWebviewPop.getSettings().setJavaScriptEnabled(true);
    mWebviewPop.getSettings().setSavePassword(false);
    mWebviewPop.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT));
    mContainer.addView(mWebviewPop);
    WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
    transport.setWebView(mWebviewPop);
    resultMsg.sendToTarget();

    return true;
}

@Override
public void onCloseWindow(WebView window) {
    Log.d("onCloseWindow", "called");
}
}
}

The key for this issue is onCreateWindow. A new window is created and inserted to the frame layout and removed upon success. I added the removal at shouldOverrideUrlLoading.

Share:
18,716
Stefan
Author by

Stefan

Updated on June 05, 2022

Comments

  • Stefan
    Stefan almost 2 years

    I'm trying to make facebook like functionality in Android WebView (project specification does not allow browser opening, or any out of application activity).

    So, restrictions are that it has to be done in WebView. I've managed to make it a dialog, and apon user's click like button, it (the WebView) redirects successfully (in the same view) to facebooks login page. After successful authentication, the WebView (in a dialog) is redirected to blank page with facebook header.

    Interestingly enough, when user leaves the blank dialog and click again on the like button it works like perfectly (like and unlike) - it somehow keeps authentication active. To resolve the blank page, I've tried/used following:

    • using WebViewClient and shouldOverloadUrlForwarding to keep whole process in same WebView dialog.
    • using WebChromeClient to properly execute JavaScript - without it after login is not possible to like/unlike.
    • tried using setUserAgentString() to simulate other browsers like Chrome or Firefox
    • tried the SSL Error certificate handling (in API level 8) (at WebViewClient)

      @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); }

    • using (and all possible combination of these)

      webView.getSettings().setAppCacheEnabled(true); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);

    • Tried also persisting cookies with CookieSyncManager, CookieManager and manually handling.

    All of this was with no result. I really appreciate any help!

  • ir2pid
    ir2pid almost 13 years
    how do you intercept a webview request and redirect it ?
  • Blundell
    Blundell over 12 years
    @user838355 , see my answer :-)
  • Tyler Collier
    Tyler Collier over 12 years
    This worked for me. But there's another problem. Normally the webview can save its state and not reload on orientation changes by making use of webView.saveState() and webView.restoreState(), but the solution presented here is kind of a 'double load' thing, and kind of defeats the orientation change save/restore state code. Anyone have a solution/workaround?
  • Tyler Collier
    Tyler Collier over 12 years
    To answer my question, I made use of onConfigurationChanged(). See: stackoverflow.com/questions/1002085/…
  • Abhijit
    Abhijit over 12 years
    @Blundell- Could you please tell me what getFacebookLikeUrl() returns: is it just the URL that the user intended to like?
  • Blundell
    Blundell over 12 years
    @Abhijit Yeah it's just the facebook url from their API to 'like' a post.
  • Yevgeny Simkin
    Yevgeny Simkin about 12 years
    could someone please post an example of what getFacebookLikeUrl() returns? I'm totally stumped by what url this is meant to be or where one gets it.
  • Chandra Sekhar
    Chandra Sekhar almost 12 years
    @Blundell I am facing the exact situation. Trying hard to find a solution. Can you please help me understanding what is getFacebookLikeUrl() method? Is it a user defined one or from some library. I have posted a question on stackoverflow.com/questions/11208427/… please help me.
  • Blundell
    Blundell almost 12 years
    @ChandraSekhar I can't really remember, but I defined it myself cantremember.com
  • Chandra Sekhar
    Chandra Sekhar almost 12 years
    @Blundell I didn't find that. Please share the specific uri