Facebook login in Android apps – Using latest SDK

Facebook Login allows you to obtain a token to access Facebook’s API on behalf of someone using your app. You can use this feature in place of building your own account system or to add Facebook services to your existing accounts.

This tutorial explains how to use Facebook SDK APIs in Android. This tutorial allows user  create app which which will perform following actions

  1. Login to Facebook
  2. Share status message to Facebook wall

This example using Facebook SDK 3.22 for Android which is available for free download from the Facebook’s developer console. This Facebook SDK comes with almost all the functionality of the native Facebook app to your own Android app.

Lets get started :

There are two parts of tutorial

  1. Setting up facebook application in developer console
  2. Creating android application

Set up facebook application in developer console.

1. Open developers.facebook.com. login into account if you are not already logined.

2. Create a new app by clicking “Add a new app” on “My Apps” in developer console.

3. Now you will be presented with dialog to choose for which kind of app you want to create which will use facebook login. Choose android in this dialog.

4. After you will be asked for name of you facebook app. Just write “LoginTest” and then click on “create new facebook app ID”.

5. Now you will be asked to choose for category of your fb app . Choose “productivity” in this and hit “Create App ID

6. Next you will be presented option to download SDK and Facebook apk for emulator. download both file and save on computer. these will be used later in tutorial.

7. After downloading you will be asked for package name and Main Launcher activity of your application.

Insert com.example.facebook in Package name field and com.example.facebook.MainActivity in Default Activity Class Name.

8. Now we have to create key hash for fb application. For this task you must have keytool utility and openssl library in your path system variable. If you dont have this setup please follow this link.

Now open command prompt and run following command
keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64

This will ask for password. Default password is “android” . now enter password and press enter.Now a alphanumberic key will be generated on command prompt. Copy this key.

9. Now copy this key Hash to “Development Key Hashes” field.

10. Now if scroll down then you are presented with finished icon. This shows you are finished. But you have to make a few more changes to get this app working.

11. Now click on “Settings” in developer console then you will be presented with basic info. Now enter your email id in “Contact email” field. and then save the changes. You need to provide this info otherwise your facebook app will not be activated.

12. Now click on “Status & Review” on left side of dash board. Now turn on the toggle button and your app will be activated.

13. There will be final confirmation. Confirm this .

14. Now your app is ready to be used. This green dot signify this.

Now the app setup from face book side is done. Now you need to create app on android in eclipse.

Creating Android application:

1. Create new application

File -> New -> Android Project with name Facebook and package name must be com.example.facebook .

2. Import FacebookSDK

Now import FacebookSDK you downloaded earlier into eclipse.

  1. File > Import > Android > Existing Android Code Into Workspace > Next
  2. Now click on Browse and select the folder in which you extracted FacebookSDK and press OK .
  3. It will show list of projects to import. Only select FacebookSDK from that and press finsih.

 3. Add FacebookSDK as library

You have to add FacebookSDK as library in Facebook project you created earlier.

  1. Right click on Facebook project and click on properties.
  2. Now click on android.
  3. Now click on add in “Library” segment.
  4. There will be FacebookSDK in the list. choose this and click ok.

4. Update activity_main.xml

Now update activity_main.xml file with code below. In this code we are adding a facebook login button which will also act as logout button when user is logined. We are also adding user greeting which will show name of user when logined. User profile pic will also be shown when user is logged in and below it we have a status update button.

[xml] <?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:facebook=”http://schemas.android.com/apk/res-auto”
android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:background=”#FFF”
>
<LinearLayout android:orientation=”vertical”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”
android:background=”#FFF”
android:id=”@+id/main_ui_container”>
<com.facebook.widget.LoginButton
android:id=”@+id/login_button”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginTop=”5dp”
facebook:confirm_logout=”false”
facebook:fetch_user_info=”true”
/>
<LinearLayout
android:layout_width=”150dp”
android:layout_height=”wrap_content”
android:layout_gravity=”center_horizontal”
android:gravity=”center_horizontal”
android:orientation=”vertical”>
<TextView
android:id=”@+id/greeting”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_marginLeft=”10dp”
android:layout_gravity=”center”
android:textColor=”#333″
android:textSize=”18sp”/>
<com.facebook.widget.ProfilePictureView
android:id=”@+id/profilePicture”
android:layout_height=”wrap_content”
android:layout_width=”wrap_content”
android:gravity=”center_horizontal”
android:layout_marginBottom=”10dp”
facebook:preset_size=”normal”/>
<Button
android:id=”@+id/postStatusUpdateButton”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:text=”Post Status Update”
/>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id=”@+id/fragment_container”
android:layout_width=”fill_parent”
android:layout_height=”fill_parent”/>

</LinearLayout>
[/xml]

 5. Update AndroidManifest.xml

We have to add INTERNET permission to manifest. Along with facebook LoginActivity and some meta data which will refer to app id we created on facebook developer site.

[xml highlight=”11,26-33″] <?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”com.example.facebook”
android:versionCode=”1″
android:versionName=”1.0″ >

<uses-sdk
android:minSdkVersion=”9″
android:targetSdkVersion=”21″ />

<uses-permission android:name=”android.permission.INTERNET” />

<application
android:allowBackup=”true”
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name” >
<activity
android:name=”.MainActivity”
android:label=”@string/app_name” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<activity
android:name=”com.facebook.LoginActivity”
android:label=”@string/app_name”
android:theme=”@android:style/Theme.Translucent.NoTitleBar” />

<meta-data
android:name=”com.facebook.sdk.ApplicationId”
android:value=”@string/app_id” />
</application>

</manifest>
[/xml]

6. Also update Strings.xml

In this please update app_id with your app id. Go to developers.facebook.com and login with account in which you created facebook application in previous section. There you can find app ID. copy that id here.

[xml highlight=”4″] <?xml version=”1.0″ encoding=”utf-8″?>
<resources>
<string name=”app_name”>Facebook</string>
<string name=”app_id”>1392862814355419</string>
<string name=”cancelled”>Cancelled</string>
<string name=”permission_not_granted”>Unable to perform selected action because permissions were not granted.</string>
<string name=”ok”>OK</string>
<string name=”hello_user”>Hello %1$s!</string>
<string name=”success”>Success</string>
<string name=”successfully_posted_post”>Successfully posted \’%1$s\’.\nPost ID: %2$s</string>
<string name=”error”>Error</string>
<string name=”status_update”>Updating status for %1$s at %2$s</string>
</resources>
[/xml]

7. Update MainActivity.java

The UiLifecycleHelper class constructor takes in a Session.StatusCallback listener implementation that you can use to respond to session state changes by overriding the listener’s call()method. You’ll define a private method in your main fragment class called onSessionStateChange()that is invoked from the call() method. You’ll primarily be interested in session state changes that transition to opened or closed.

To ensure that the sessions are set up correctly, your fragment must override the fragment lifecycle methods:

onCreate()onResume()onPause()onDestroy()onActivityResult()

and onSaveInstanceState() and call the corresponding UiLifecycleHelper methods.

For example, calling the onCreate() method in the UiLifecycleHelper object creates the Facebook session and opens it automatically if a cached token is available.

During the authentication flow, the results are returned back to the main activity by default. Your activity would need to handle the results by overriding the onActivityResult() method. To allow the fragment to receive the onActivityResult() call rather than the activity, you can call thesetFragment() method on the LoginButton instance.

[java] package com.example.facebook;

import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.*;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphPlace;
import com.facebook.model.GraphUser;
import com.facebook.widget.*;

import java.util.Date;
import java.util.List;

public class MainActivity extends FragmentActivity {
String TAG=”MainActivity”;
private static final String PERMISSION = “publish_actions”;

private final String PENDING_ACTION_BUNDLE_KEY = “pending_action”;

private Button postStatusUpdateButton;
private LoginButton loginButton;
private ProfilePictureView profilePictureView;
private TextView greeting;
private PendingAction pendingAction = PendingAction.NONE;
private GraphUser user;
private GraphPlace place;
private List<GraphUser> tags;
private boolean canPresentShareDialog;

private enum PendingAction {
NONE, POST_STATUS_UPDATE
}

private UiLifecycleHelper uiHelper;

private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};

private FacebookDialog.Callback dialogCallback = new FacebookDialog.Callback() {
@Override
public void onError(FacebookDialog.PendingCall pendingCall,
Exception error, Bundle data) {
Log.d(TAG, String.format(“Error: %s”, error.toString()));
}

@Override
public void onComplete(FacebookDialog.PendingCall pendingCall,
Bundle data) {
Log.d(TAG, “Success!”);
}
};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
// Can we present the share dialog for regular links?
canPresentShareDialog = FacebookDialog.canPresentShareDialog(this,FacebookDialog.ShareDialogFeature.SHARE_DIALOG);

if (savedInstanceState != null) {
String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY);
pendingAction = PendingAction.valueOf(name);
}

setContentView(R.layout.activity_main);

loginButton = (LoginButton) findViewById(R.id.login_button);
loginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
@Override
public void onUserInfoFetched(GraphUser user) {
MainActivity.this.user = user;
updateUI();
// It’s possible that we were waiting for this.user to
// be populated in order to post a status update.
handlePendingAction();
}
});

profilePictureView = (ProfilePictureView) findViewById(R.id.profilePicture);
greeting = (TextView) findViewById(R.id.greeting);

postStatusUpdateButton = (Button) findViewById(R.id.postStatusUpdateButton);
postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
performPublish(PendingAction.POST_STATUS_UPDATE,canPresentShareDialog);
}
});
}

//override lifecycle methods so that UiLifecycleHelper know about state of the activity
@Override
protected void onResume() {
super.onResume();
uiHelper.onResume();
updateUI();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data, dialogCallback);
}

@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}

@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}

private void onSessionStateChange(Session session, SessionState state,Exception exception) {
if (state.isOpened()) {
Toast.makeText(getApplicationContext(), “User logged in…”, Toast.LENGTH_SHORT).show();
} else if (state.isClosed()) {
Toast.makeText(getApplicationContext(), “User logged out…”, Toast.LENGTH_SHORT).show();
}
if (pendingAction != PendingAction.NONE
&& (exception instanceof FacebookOperationCanceledException
|| exception instanceof FacebookAuthorizationException)) {
new AlertDialog.Builder(MainActivity.this)//if permission is not granted
.setTitle(R.string.cancelled)
.setMessage(R.string.permission_not_granted)
.setPositiveButton(R.string.ok, null).show();
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
handlePendingAction();
}
updateUI();
}

private void updateUI() {
Session session = Session.getActiveSession();
boolean enableButtons = (session != null && session.isOpened());

postStatusUpdateButton.setEnabled(enableButtons
|| canPresentShareDialog);

if (enableButtons && user != null) {
profilePictureView.setProfileId(user.getId());
greeting.setText(getString(R.string.hello_user, user.getFirstName()));
} else {
profilePictureView.setProfileId(null);
greeting.setText(null);
}
}

@SuppressWarnings(“incomplete-switch”)
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
// These actions may re-set pendingAction if they are still pending, but we assume they
// will succeed.
pendingAction = PendingAction.NONE;

switch (previouslyPendingAction) {
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
}
}

private interface GraphObjectWithId extends GraphObject {
String getId();
}

private void showPublishResult(String message, GraphObject result,
FacebookRequestError error) {
String title = null;
String alertMessage = null;
if (error == null) {
title = getString(R.string.success);
String id = result.cast(GraphObjectWithId.class).getId();
alertMessage = getString(R.string.successfully_posted_post,
message, id);
} else {
title = getString(R.string.error);
alertMessage = error.getErrorMessage();
}

new AlertDialog.Builder(this).setTitle(title).setMessage(alertMessage)
.setPositiveButton(R.string.ok, null).show();
}

// create sample post to update on facebook
private FacebookDialog.ShareDialogBuilder createShareDialogBuilderForLink() {
return new FacebookDialog.ShareDialogBuilder(this)
.setName(“Hello Facebook”)
.setDescription(“this is sample post from androidSRC.net to demonstrate facebook login in your android application”)
.setLink(“http://cs2guru.com/”);
}

private void postStatusUpdate() {
if (canPresentShareDialog) {
FacebookDialog shareDialog = createShareDialogBuilderForLink().build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else if (user != null && hasPublishPermission()) {
final String message = getString(R.string.status_update,
user.getFirstName(), (new Date().toString()));
Request request = Request.newStatusUpdateRequest(
Session.getActiveSession(), message, place, tags,
new Request.Callback() {
@Override
public void onCompleted(Response response) {
showPublishResult(message,
response.getGraphObject(),
response.getError());
}
});
request.executeAsync();
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}

//check if app has permission to publish on facebook
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains(“publish_actions”);
}

private void performPublish(PendingAction action, boolean allowNoSession) {
Session session = Session.getActiveSession();
if (session != null) {
pendingAction = action;
if (hasPublishPermission()) {
// We can do the action right away.
handlePendingAction();
return;
} else if (session.isOpened()) {
// We need to get new permissions, then complete the action when
// we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(
this, PERMISSION));
return;
}
}

if (allowNoSession) {
pendingAction = action;
handlePendingAction();
}
}
}
[/java]

8. Now build and run application

You can add the UiLifecycleHelper and set up a corresponding Session.StatusCallbacklistener in any activity or fragment where you wish to track and respond to session state changes.

9. Resources :

https://developers.facebook.com/docs/android/login-with-facebook/v2.2

For any queries please Comment below.

guru

Technology enthusiast. Loves to tinker with things. Always trying to create something wonderful using technology. Loves coding for Android, Raspberry pi, Arduino , Opencv and much more.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *