Tuesday 5 March 2013

A 30 minute guide to integrating Facebook in your Android application

Introduction

The goal of this article is to get Facebook integration up & running from your Android app in 30 minutes. The guide will show you how to
  • setup a Faceook test account
  • register a Facebook application
  • authenticate the user in your Android application.
  • have the user update his Facebook wall from your Android application.
This guide is accompanied  by a sample application that’s available in Github in the AndroidFacebookSample repository. To import this project in Eclipse, I suggest using the EGit plugin that can be installed via the Main P2 Repository located at http://download.eclipse.org/egit/updates.
Before running this project, make sure you change the com.ecs.android.facebook.Sample.AndroidFacebookSample file to include your Facebook API key (see subsequent section).
Once you have sample application up & running, you can copy the relevant classes into your projects to have Facebook up & running from your Android application.
First things first … In order to integrate with Facebook, you need 2 things :
  • A Facebook test account, used in our Android application to login to Facebook and make status updates.
  • A Facebook application, used to inform the user in your Android application that this application is requesting you to login to Facebook.

Facebook Test Account

We’ll start by creating a test account that we’ll use in our Android application. Signup for a new user account at Facebook. If you already have an account, sign up for a new account using your existing name but specify a different email address. Once the account has been created, we’ll convert it into a Facebook test account.
Note : The following step should not be done on your real facebook account. Converting an existing Facebook account into a test account is irreversible, so please ensure that you do the following step with your newly created “dummy” account.
When logged into Facebook, goto the Facebook Become Test Account page  to convert your newly created account into a Facebook test account. Again, do not execute these steps on your “real” user account.

After confirming that you want to convert your account into a test account, you should see the following message :

Facebook Application

Next step is to create a Facebook application. Integration with facebook is based on OAuth 2.0 and requires your to register a Facebook application. Visit the Facebook Developers Authentication page for more information on its OAuth 2.0 implementation.
The Facebook application that we’ll create will have it’s own Application ID that we’ll use in our Android application.
Creating an application cannot be done on the Facebook test account, so you’ll need to have a proper Facebook account in order to create the application. Using your “real” Facebook account, goto the Facebook Create Application page  and create your application.
Give it a name, and complete the registration. You should land on a page like this :

So far so good, everything is setup on the Facebook front, now it’s time to start coding our Android application.
On the Android front, we’ll use the Facebook Android SDK located at Github : https://github.com/facebook/facebook-android-sdk
The Facebook Android SDK is licensed under the Apache License and is completely open source.
The project contains several samples in the examples folder, but the core SDK is located in the facebook folder. The sample application included in the facebook sdk repository provides the user the ability to post a message on the wall using a custom dialog, allowing the user to enter some text. The goal of the sample application that we’ll be creating here is to send an automated message to the wall, without any human interaction. Our application will generate a piece of text and post it on the wall without showing a dialog to the user. The user simply presses a button, and the generated message will appear on his/her wall.
But to get started, we’ll begin by importing the facebook project (containing the actual facebook sdk) into Eclipse. Once this is done, you should have the following Eclipse Project in your workspace :

As this is the library project that our sample application will use to do the actual  Facebook integration, we’ll  need to create a reference in our own project to this Facebook Android SDK project. This is done by going to our project properties, select Android on the left, go to the library section and click Add.
On the following screen, you can select the Facebook Android SDK library project
When selected, it will be made available to your own project.
As you can see in the Eclipse Package explorer, our sample project now also contains a reference to the Facebook Android SDK project

The Facebook SDK project revolves around a central com.facebook.android.Facebook.Facebook class, allowing you to perform various calls to Facebook.  It provides basic login/logoff functionality (by leveraging single sign on capabilities if you have the official facebook app installed), handles the OAuth integration, and provides you with a generic API to perform requests to the various Facebook APIs.
In our own sample application, we’ll encapsulate all the Facebook interactions in a FacebookConnector object. The object is constructed like this
01public FacebookConnector(String appId,Activity activity,Context context,String[] permissions) {
02    this.facebook = new Facebook(appId);
03 
04    SessionStore.restore(facebook, context);
05    SessionEvents.addAuthListener(mSessionListener);
06    SessionEvents.addLogoutListener(mSessionListener);
07 
08    this.context=context;
09    this.permissions=permissions;
10    this.mHandler = new Handler();
11    this.activity=activity;
12}
As you can, under the hook, our FacebookConnector class uses the Facebook class provided by the Facebook SDK project.
Our FacebookConnector will provide a more coarse-grained API than the Facebook class. The Facebook class is designed in a very generic way, allowing you to do a lot of different calls to Facebook. This design results in a fairly fine-grained API, where some knowledge is expected from the application using this API. For example, you’ll need to know the specific endpoints for post a message on a wall, or to retrieve a user profile. In addition to that, you’ll also need to know what parameters you need to send for each request.
Our FacebookConnector exposes a coarse-grained method called postMessageOnWall that’s the main logic behind our Post button. The only thing we need to provide is the actual message we want to post. The FacebookConnector will do the necessary plumbing towards the more generic Facebook class.
The postMessageOnWall method checks if we have a valid Facebook session (meaning we have authenticated properly against Facebook). If this is the case, it setups up the necessary parameters, and does a call through the Facebook class to post a message on the wall. (using the me/feed endpoint)
01public void postMessageOnWall(String msg) {
02    if (facebook.isSessionValid()) {
03        Bundle parameters = new Bundle();
04        parameters.putString("message", msg);
05        try {
06            String response = facebook.request("me/feed", parameters,"POST");
07            System.out.println(response);
08        } catch (IOException e) {
09            e.printStackTrace();
10        }
11    } else {
12        login();
13    }
14}
But we’ll start by explaining what happens if the user doesn’t have a valid Facebook session.
If the user hasn’t authenticated to Facebook yet we need to perform a login. The login() is defined like this :
1public void login() {
2    if (!facebook.isSessionValid()) {
3        facebook.authorize(this.activity, this.permissions,Facebook.FORCE_DIALOG_AUTH,new LoginDialogListener());
4    }
5}
The login method is implemented in such a way that when we don’t have a logged in user, we call the facebook.authorize to start the Facebook OAuth flow. Although the Facebook SDK has a single-sign-on option, allowing you to leverage your existing facebook session you may have with the official Facebook Android application, we’ll add the Facebook.FORCE_DIALOG_AUTH parameter to have the Facebook SDK pop the login dialog.
The first thing that will happen when executing this method, is that the Facebook login dialog will be shown. Notice how the login dialog mentions the Facebook app we created earlier. By passing on our Application ID to the Facebook object, the user is now informed that the TestAndroidIntegration application is initiating the Facebook login. The user can decide at this point if he wants to login to his Facebook account.

When the user does a login, he’ll be presented with yet another dialog. Keep in mind that at this point, although the user is logged in, he didn’t give any permissions yet for this application to post messages on his wall. This particular dialog will now request the user for certain permission.
It basically allows the user to authorize the TestAndroidIntegration application to access basic information and Post to my Wall.  Accessing basic information is the default permission that is given when a user logs in this way. Here, an additional permission is requested (Post to my Wall).
In order to post something on the wall, the publish_stream permission is required, hence we pass this on to our FacebookConnector :
1private static final String FACEBOOK_APPID = "PUT YOUR FACEBOOK APPID HERE";
2private static final String FACEBOOK_PERMISSION = "publish_stream";
3 
4facebookConnector = new FacebookConnector(FACEBOOK_APPID, this, getApplicationContext(), new String[] {FACEBOOK_PERMISSION});
Note : ensure that you provide a proper Facebook APPID here.

When the user allows this request for permission (authorization), the Facebook API can begin executing requests on behalf of the user (like posting something on his wall).

Posting a message on the Facebook wall

In order to post a message on the wall, we basically construct a message (Bundle) that we pass on to the facebook request method. We use the “me/feed” ID on the Facebook Graph API to indicate that we’ll be posting something to the Profile feed (Wall in Facebook terminlogy).
01private FacebookConnector facebookConnector;
02 
03private void postMessageInThread() {
04    Thread t = new Thread() {
05        public void run() {
06 
07            try {
08                facebookConnector.postMessageOnWall(getFacebookMsg());
09                mFacebookHandler.post(mUpdateFacebookNotification);
10            } catch (Exception ex) {
11                Log.e(TAG, "Error sending msg",ex);
12            }
13        }
14    };
15    t.start();
16}
The postMethodOnWall() method is called from our main Activity in a background thread. Although we don’t want to interrupt the main UI thread while posting the message (hence the background thread), we do want to send a notification to the user that his message was posted. We use a handler for this in order to show a Toast message on the main UI thread once the background processing has been done.
1private FacebookConnector facebookConnector;
2 
3final Runnable mUpdateFacebookNotification = new Runnable() {
4    public void run() {
5        Toast.makeText(getBaseContext(), "Facebook updated !", Toast.LENGTH_LONG).show();
6    }
7};
An importing thing to note is that when the user clicks the Post Message button, besides logging just logging in, we also want to send the message to the Facebook wall. Performing the login, immediately followed by an action (in this case sending a message) can be done by adding a AuthenticationListener (SessionEvents.AuthListener) to the SessionEvents.
The following code (wrapper method) illustrates this :
  • in case of logged in user simply post the message in the background thread.
  • in case of an anonymous user, we wait for the authentication to succeed, and then continue on to posting the message in the background thread.
01public void postMessage() {
02    if (facebookConnector.getFacebook().isSessionValid()) {
03        postMessageInThread();
04    } else {
05        SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {
06 
07            @Override
08            public void onAuthSucceed() {
09                postMessageInThread();
10            }
11 
12            @Override
13            public void onAuthFail(String error) {
14 
15            }
16        };
17        SessionEvents.addAuthListener(listener);
18        facebookConnector.login();
19    }
20}
The clearCredentials() method is responsible for logoff functionality. All credentials are cleared from the system, and each interaction with Facebook will again trigger a login().
1private void clearCredentials() {
2    try {
3        facebookConnector.getFacebook().logout(getApplicationContext());
4    } catch (MalformedURLException e) {
5        e.printStackTrace();
6    } catch (IOException e) {
7        e.printStackTrace();
8    }
9}

Conclusion

The Android Facebook SDK provides an easy way to integrate Facebook into your Android application. It provides single sign on capabilities, preventing the user from having to login again if a session was already established with Facebook. Also, the OAuth 2.0 implementation that Facebook offers enables a much simpler authentication / authorization mechanism that with traditional OAuth based providers. After having setup the test account to do your testing, you should be up & running with facebook in your application in no time.

Android Threads comparision



ServiceThreadIntentServiceAsyncTask
When to use ?Task with no UI, but shouldn't be too long. Use threads within service for long tasks.- Long task in general.

- For tasks in parallel use Multiple threads (traditional mechanisms)
- Long task usually with no communication to main thread.
(Update)- If communication is required, can use main thread handler or broadcast intents[3]

- When callbacks are needed (Intent triggered tasks). 
- Long task having to communicate with main thread.

- For tasks in parallel use multiple instances OR Executor [1]
TriggerCall to method
onStartService()
Thread start() methodIntentCall to method execute()
Triggered From (thread)Any threadAny ThreadMain Thread (Intent is received on main thread and then worker thread is spawed)Main Thread
Runs On (thread)Main ThreadIts own threadSeparate worker threadWorker thread. However, Main thread methods may be invoked in between to publish progress.
Limitations /
Drawbacks
May block main thread- Manual thread management

- Code may become difficult to read
- Cannot run tasks in parallel.

- Multiple intents are queued on the same worker thread.
- one instance can only be executed once (hence cannot run in a loop) [2]

- Must be created and executed from the Main thread