Facebook comments plugin lets users to comment on any web url using their Facebook account. Right now Facebook doesn’t provide native android support for the plugin, but we can integrate it in our app using the WebView and make it looks native. This article not only explains how to add the fb comments widget, but also covers how to load a full article, particularly when you are designing a newsfeed app.
1. Creating New Project
We’ll start by setting up basic project by adding the required files and icons. So let’s get started.
1. Create a new project in Android Studio from File ⇒ New Project by filling the required details.
2. Open app/build.gradle and add design support library dependency. This step is optional, but needed for toolbar styling.
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' // design support library compile 'com.android.support:design:23.0.1' }
3. Open strings.xml and add the below string values.
<resources> <string name="app_name">Facebook Comments</string> <string name="title_activity_comments">Comments</string> <string name="action_comment">Comment</string> <string name="action_refresh">Reload</string> </resources>
4. Download the below material drawable icons and add them to projects res folder. These icons will be used for floating action button and for the toolbar icon.
> Comment icon (Used for Floating Action Button)
> Refresh icon (Used as toolbar icon to refresh the facebook comments)
5. Open styles.xml located under res ⇒ values and make sure you have the below styles as app might crash because of the toolbar.
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> </resources>
6. Open AndroidManifest.xml and add INTERNET permission. You can notice FbCommentsActivity is also added here. We’ll create this activity shortly.
<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="info.androidhive.fbcommentwidget"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".FbCommentsActivity" android:label="@string/title_activity_comments" android:theme="@style/AppTheme.NoActionBar" /> </application> </manifest>
2. Loading the Article
Now we’ll modify our main activity to load a full article using the WebView. We’ll also add a floating action button which loads the facebook comments activity.
7. Open the layout file main activity (activity_main.xml) and the below code. This layout contains a toolbar and a web view to load the web page.
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:fitsSystemWindows="true"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_insert_comment_white_24dp" /> </android.support.design.widget.CoordinatorLayout>
8. Open MainActivity.java and add the below code. Here we are loading the firebase article url in web view.
package info.androidhive.fbcommentwidget; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.webkit.WebView; public class MainActivity extends AppCompatActivity { // This url contains the content of the article excluding web page's // header, footer, title, comments private static String url = "https://api.androidhive.info/facebook/firebase_analytics.html"; private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.web_view); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // launching facebook comments activity Intent intent = new Intent(MainActivity.this, FbCommentsActivity.class); // passing the article url intent.putExtra("url", "https://www.androidhive.info/2016/06/android-firebase-integrate-analytics/"); startActivity(intent); } }); // loading web page webView.loadUrl(url); } }
Now if you run the app, you should see the full article loading as shown in the below image.
3. Adding Facebook Comment Widget
9. Create a menu file fb_comments.xml under res ⇒ menu and add the below menu option. This menu is used to add the refresh icon to toolbar.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_refresh" android:icon="@drawable/ic_refresh_white_24dp" android:orderInCategory="100" android:title="@string/action_refresh" app:showAsAction="always" /> </menu>
10. Create a new activity named FbCommentsActivity.java and add the below code to its layout file (activity_fb_comments.xml)
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".FbCommentsActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/webview_frame" android:layout_width="match_parent" android:layout_height="match_parent"> <WebView android:id="@+id/commentsView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" /> <ProgressBar android:id="@+id/progressBar" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_gravity="center" android:layout_marginBottom="10dp" android:indeterminateTint="@color/colorPrimary" android:indeterminateTintMode="src_atop" /> </FrameLayout> </LinearLayout> </android.support.design.widget.CoordinatorLayout>
11. Open FbCommentsActivity.java and do the below changes. This activity contains necessary functions to load the Facebook widget plugin in WebView.
Below is the actual HTML & JS of Facebook comment widget.
<!doctype html> <html lang="en"> <head></head> <body> <div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <div class="fb-comments" data-href="https://www.androidhive.info/2016/06/android-firebase-integrate-analytics/" data-numposts="5" data-order-by="reverse_time"></div> </body> </html>
package info.androidhive.fbcommentwidget; import android.net.Uri; import android.net.http.SslError; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.webkit.ConsoleMessage; import android.webkit.CookieManager; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.ProgressBar; import android.widget.Toast; public class FbCommentsActivity extends AppCompatActivity { private static String TAG = FbCommentsActivity.class.getSimpleName(); private WebView mWebViewComments; private FrameLayout mContainer; private ProgressBar progressBar; boolean isLoading; private WebView mWebviewPop; private String postUrl; // the default number of comments should be visible // on page load. private static final int NUMBER_OF_COMMENTS = 5; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fb_comments); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); mWebViewComments = (WebView) findViewById(R.id.commentsView); mContainer = (FrameLayout) findViewById(R.id.webview_frame); progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar.setVisibility(View.VISIBLE); postUrl = getIntent().getStringExtra("url"); // finish the activity in case of empty url if (TextUtils.isEmpty(postUrl)) { Toast.makeText(getApplicationContext(), "The web url shouldn't be empty", Toast.LENGTH_LONG).show(); finish(); return; } setLoading(true); loadComments(); } private void loadComments() { mWebViewComments.setWebViewClient(new UriWebViewClient()); mWebViewComments.setWebChromeClient(new UriChromeClient()); mWebViewComments.getSettings().setJavaScriptEnabled(true); mWebViewComments.getSettings().setAppCacheEnabled(true); mWebViewComments.getSettings().setDomStorageEnabled(true); mWebViewComments.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); mWebViewComments.getSettings().setSupportMultipleWindows(true); mWebViewComments.getSettings().setSupportZoom(false); mWebViewComments.getSettings().setBuiltInZoomControls(false); CookieManager.getInstance().setAcceptCookie(true); if (Build.VERSION.SDK_INT >= 21) { mWebViewComments.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); CookieManager.getInstance().setAcceptThirdPartyCookies(mWebViewComments, true); } // facebook comment widget including the article url String html = "<!doctype html> <html lang=\"en\"> <head></head> <body> " + "<div id=\"fb-root\"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = \"//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6\"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> " + "<div class=\"fb-comments\" data-href=\"" + postUrl + "\" " + "data-numposts=\"" + NUMBER_OF_COMMENTS + "\" data-order-by=\"reverse_time\">" + "</div> </body> </html>"; mWebViewComments.loadDataWithBaseURL("http://www.nothing.com", html, "text/html", "UTF-8", null); mWebViewComments.setMinimumHeight(200); } private void setLoading(boolean isLoading) { this.isLoading = isLoading; if (isLoading) progressBar.setVisibility(View.VISIBLE); else progressBar.setVisibility(View.GONE); invalidateOptionsMenu(); } private class UriWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { String host = Uri.parse(url).getHost(); return !host.equals("m.facebook.com"); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); String host = Uri.parse(url).getHost(); setLoading(false); if (url.contains("/plugins/close_popup.php?reload")) { final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { //Do something after 100ms mContainer.removeView(mWebviewPop); loadComments(); } }, 600); } } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { setLoading(false); } } class UriChromeClient extends WebChromeClient { @Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { mWebviewPop = new WebView(getApplicationContext()); mWebviewPop.setVerticalScrollBarEnabled(false); mWebviewPop.setHorizontalScrollBarEnabled(false); mWebviewPop.setWebViewClient(new UriWebViewClient()); mWebviewPop.setWebChromeClient(this); mWebviewPop.getSettings().setJavaScriptEnabled(true); mWebviewPop.getSettings().setDomStorageEnabled(true); mWebviewPop.getSettings().setSupportZoom(false); mWebviewPop.getSettings().setBuiltInZoomControls(false); mWebviewPop.getSettings().setSupportMultipleWindows(true); 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 boolean onConsoleMessage(ConsoleMessage cm) { Log.i(TAG, "onConsoleMessage: " + cm.message()); return true; } @Override public void onCloseWindow(WebView window) { } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. if (!isLoading) { getMenuInflater().inflate(R.menu.fb_comments, menu); } return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { onBackPressed(); return true; } if (item.getItemId() == R.id.action_refresh) { mWebViewComments.reload(); } return super.onOptionsItemSelected(item); } }
Whenever you want to load the Facebook comments for any url, just start this activity as below by passing the url in intent data.
// launching Facebook comments activity Intent intent = new Intent(MainActivity.this, FbCommentsActivity.class); // passing the article url intent.putExtra("url", "https://www.androidhive.info/2016/06/android-firebase-integrate-analytics/"); startActivity(intent);
Run the app and click on FAB to load the Facebook comment widget.
Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: ravi@androidhive.info
Nice one ravi. Btw can you do a tutorial on dagger 2 dependency injection library and android model view presenter(MVP) pattern?
I’ll check the library.
Why have we used a Progress Bar in this? Is that for the refresh part?
Yes, on initial load and on refresh. But the progressbar is disappearing immediately but Facebook widget is taking time to load.
That means facebook widget is loading on the same WebView ?
do user need to login each time?
Nope. Only once.
Can you make tutorial help me to upload image and text from android to mysql database
Try this
http://www.androidhive.info/2014/12/android-uploading-camera-image-video-to-server-with-progress-bar/
Nice. Thank you
Your apk app crashes when I try to refresh!
what is the purpose and where is this file?
“/plugins/close_popup.php?reload”
Thank you
it is really swesome ravi… i was looking for.
@Ravi Tamada:disqus Using Facebook SDK or Auth token, which is getting from Azure or Fire-base can user comment directly without login again?
Please create a tutorial for PDF in android.
How can we download and display pdf files in android app.
Can you write an article about transition in android because I couldn’t find anything useful about that
@Ravi Tamada Please can you create a tutorial for PDF/document viewer in android also how to integrate downloads and uploads to a centralized cloud storage with admin rights for the developer
http://www.androidhive.info/2016/05/android-build-intro-slider-app/
in this tutorial ,
App Intro going to cruss in pre lolipop device when mainactivity is open..
pls solve it!
Check the LogCat for errors.
Bookmarked ! Thanks!
You are welcome 🙂
Ravi can I use any url here?
intent.putExtra(“url”, “http://www.androidhive.info/2016/06/android-firebase-integrate-analytics/”);
startActivity(intent);
Do I have to have the comments plugin on my web page before using the link to my web page in my android app???? or can I just use any url?
nice
it says, the web page could not be loaded because net::ERR_CACHE_MISS
Hi,
Its really helpful. i have an doubt when i will press post button also tick on fb comment but i won’t post on my page in fb.
Hey Ravi,
Can you please give ,me a clear explanation on why you need to pass the url to the CommentingActivity.
Hey,
Whenever I click on ‘Log In to Post’ button it says THE PAGE YOU REQUESTED WAS NOT FOUND.
It was working fine before. But now it throws this error. Help please.
Great tutorial!!!! Please Sir also do a project for implementing Blogger API in Android App
when i press on the name , webview disappears what should i do ?
Nice tutorial Ravi. But I want to know how to do if we want to refresh comments automatically. Thanks
emoji such as 🙂 not work and show ? instead. How to solve?
hi this is not working on jelly bean devices can you please check. I also tried sample apk but its not working
is it possible to integrate the plugin without using the user facebook account? I want user comment with his account created in my application,
I want this feature too. Did you implemented it ?
@Ravi Really nice job you had done. but comment was not posted on facebook wall
Great Tutorial !, thanks
Cheers!
Tks for great tutorial Ravisan
You are welcome 🙂
WORKING PERFECTLY ON MY NEWS APP!!! THANKS FOR SHARING THIS!
Now i am going to see if i can increase the webview font size so that it looks more mobile friendly
How do you create a new page without any comment?
You are welcome 🙂
Thanks for great tutorial.
You are welcome 🙂
Hi Ravi, Where those comments are getting displayed under the articles??
Its showing in app is fine. But As, post url is of article, those comments are not displaying in website. How it works.. can you please explain…
Thanks Da.
can i get the same comments data via webhook to my own server
How to add delete button on comment
this is for single page.
If i have multiple pages how can code it??