Android WebView for Facebook Like Button
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
.
Stefan
Updated on June 05, 2022Comments
-
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
andshouldOverloadUrlForwarding
to keep whole process in sameWebView
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!
- using
-
ir2pid almost 13 yearshow do you intercept a webview request and redirect it ?
-
Blundell over 12 years@user838355 , see my answer :-)
-
Tyler Collier over 12 yearsThis 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()
andwebView.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 over 12 yearsTo answer my question, I made use of
onConfigurationChanged()
. See: stackoverflow.com/questions/1002085/… -
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 over 12 years@Abhijit Yeah it's just the facebook url from their API to 'like' a post.
-
Yevgeny Simkin about 12 yearscould 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 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 almost 12 years@ChandraSekhar I can't really remember, but I defined it myself cantremember.com
-
Chandra Sekhar almost 12 years@Blundell I didn't find that. Please share the specific uri