In order to start using Facebook API in you application, you'll need to download and extract the SDK ZIP file. By enabling Facebook integrations, including through this SDK, you can share information with Facebook, including information about people’s use of your app.
To import the SDK library project and the samples, with the new SDK, go to Eclipse's File > Import menu, and select General' / 'Existing Projects into Workspace.
Browse to select the root of your SDK folder, facebook-android-sdk-master. The SDK should appear in the list as 'FacebookSDK' . For this tutorial we don't need the samples so deselect them.
Click 'Finish'. If the project is showing errors, simply use Project > Clean in Eclipse to refresh all the project's states. It is also possible that your Eclipse compiler level has not matched that required by Android. If you see errors like "Android requires compiler compliance level 5.0 or 6.0.", simply make sure the project (or Eclipse) properties mandate v1.6 in the Java Compiler section.
The next step is to create Facebook App. To do this go to App Dashboard, on the Facebook Developers site. Click 'Create New App', and enter basic information such as its name and a unique namespace.
Once created, note down the app ID shown at the top of the dashboard page. You'll need to add this to your project files. Next you'll need to create Android key hashes to associate with the app.The key hash is used by Facebook as a security check for authenticity. Every Android app you'll create will be signed, and you will need to register each app's key hash with Facebook as a security check for authenticity. To generate your key hash on your local computer, run Java's keytool utility (which should be on your console's path) against the Android debug keystore. This is, by default, in your home .android directory). On Windows, use:
keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64
You will be prompted for a password. This should be 'android' without quotes. You'll then be given a key hash of 30 characters or so. (If you are not prompted for a password, something is wrong and you must check your paths above to ensure the debug.keystore is present.).
It you are not registered as a facebook developer, go to the Facebook Developer site. Make sure you are logged into Facebook and, using the dropdown menu in the top-right, go to your 'Settings'.Then, go to the 'Developer Settings' section on the left. If you haven't done so yet, you will be required to quickly register as a developer.
To obtain the release key hash, use the 'keytool' in the same way as in the step above except for the alias and path.
To obtain the release key hash, use the 'keytool' in the same way as in the step above except for the alias and path.
keytool -exportcert -alias -keystore | openssl sha1 -binary | openssl base64
Make sure to use the password that you set when you first created the release key. Save this change. You will also need to return to this dashboard and add your app's package name and main activity class once you have created a new Android project itself.
Now everything is ready to start our project.
Go to File -> New -> Android Application Project to create new project. Lets call it MyFacebookProject. Define the other options of the project and click next.
Create blank activity click next and finish.MainActivity class and activity_main.xml will be automatically created. In activity_main.xml create two button - login and logout. when the user logs in the logout button will be shown.
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:id="@+id/loginButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login" /> <Button android:id="@+id/logoutButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Logout" android:visibility="gone" /> </LinearLayout>
Before we start writing some code, we will have to include the FacebookSDK library to our project. To do this, select Project -> Properties. On the Library area, click add and select FacebookSDK. You'll see something similar like the image below.
private Session.StatusCallback sessionStatusCallback; private Session currentSession;
The currentSession variable will contain the active session.
Next lets create a method that will be used to login the user. Call the method connectToFB().
/** * Connects the user to facebook */ public void connectToFB() { List<String> permissions = new ArrayList<String>(); permissions.add("publish_stream"); currentSession = new Session.Builder(this).build(); currentSession.addCallback(sessionStatusCallback); Session.OpenRequest openRequest = new Session.OpenRequest(this); openRequest.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); openRequest.setRequestCode(Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE); openRequest.setPermissions(permissions); currentSession.openForPublish(openRequest); }
Override the onActivityResult() method.
/** * this method is used by the facebook API */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (currentSession != null) { currentSession.onActivityResult(this, requestCode, resultCode, data); } }
Now lets create a method onSessionStateChange that will manage the session. In this method you can fetch user data and do other stuff when the session is open.
/** * manages the session state change. This method is called after the * <code>connectToFB()</code> method. * * @param session * @param state * @param exception */ private void onSessionStateChange(Session session, SessionState state, Exception exception) { if (session != currentSession) { return; } if (state.isOpened()) { // Log in just happened. Toast.makeText(getApplicationContext(), "session opened", Toast.LENGTH_SHORT).show(); } else if (state.isClosed()) { // Log out just happened. Update the UI. Toast.makeText(getApplicationContext(), "session closed", Toast.LENGTH_SHORT).show(); } }
In the onCreate() method instanciate the sessionStatusCallback, so it will react on session changes.
// create instace for sessionStatusCallback sessionStatusCallback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { onSessionStateChange(session, state, exception); } };
Also in the onCreate method lets program the buttons login, logout and new publish button. When the user clicks on login button, login dialog will open. when the user is logged in , the login button will be hidden and the logout and publish button will be shown. When user clicks on logout button the session will be closed and the login button will be shown. First add this three lines in your class:
private Button login; private Button logout; private Button publishButton;
So now in the onCreate() method add this code:
// login button login = (Button) findViewById(R.id.loginButton); login.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { login.setVisibility(View.GONE); connectToFB(); logout.setVisibility(View.VISIBLE); publishButton.setVisibility(View.VISIBLE); } }); // logout button logout = (Button) findViewById(R.id.logoutButton); logout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (currentSession != null) { currentSession.closeAndClearTokenInformation(); logout.setVisibility(View.GONE); publishButton.setVisibility(View.GONE); login.setVisibility(View.VISIBLE); } } }); // publish button publishButton = (Button) findViewById(R.id.publishButton); publishButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { publishStory(); } });
Don't worry if you have an error on the publishStory() method. We'll write it later.Now we'll update the activity_main.xml and add the publishButton to the layout.
<Button android:id="@+id/publishButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Publish on my wall" android:visibility="gone"/>
Now we'll code the publishStory() method:
/** * Publishes story on the logged user's wall */ public void publishStory() { Bundle params = new Bundle(); params.putString("name", "test-name"); params.putString("caption", "test-caption"); params.putString("description", "test-description"); params.putString("link", "http://somewebsite.com"); params.putString("picture","http://yourimagelink/test.jpg"); WebDialog feedDialog = (new WebDialog.FeedDialogBuilder(this,currentSession, params)) .setOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(Bundle values,FacebookException error) { if (error == null) { // When the story is posted, echo the success // and the post Id. final String postId = values.getString("post_id"); if (postId != null) { // do some stuff } else { // User clicked the Cancel button Toast.makeText(getApplicationContext(), "Publish cancelled", Toast.LENGTH_SHORT).show(); } } else if (error instanceof FacebookOperationCanceledException) { // User clicked the "x" button Toast.makeText(getApplicationContext(), "Publish cancelled", Toast.LENGTH_SHORT).show(); } else { // Generic, ex: network error Toast.makeText(getApplicationContext(), "Error posting story", Toast.LENGTH_SHORT).show(); } } }).setFrom("").build(); feedDialog.show(); }
Finally add internet permission , your application id and the loginActivity to your AndroidManifest.xml file. the final version of the AndroidManifest.xml file should look like this:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mende.myfacebookproject" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id" /> <activity android:name="com.mende.myfacebookproject.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" /> </application> </manifest>
Your final MainActivity.class code should look like this:
package com.mende.myfacebookproject; import java.util.ArrayList; import java.util.List; import com.facebook.FacebookException; import com.facebook.FacebookOperationCanceledException; import com.facebook.Session; import com.facebook.SessionLoginBehavior; import com.facebook.SessionState; import com.facebook.widget.WebDialog; import com.facebook.widget.WebDialog.OnCompleteListener; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import android.app.Activity; import android.content.Intent; public class MainActivity extends Activity { private Session.StatusCallback sessionStatusCallback; private Session currentSession; private Button login; private Button logout; private Button publishButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // create instace for sessionStatusCallback sessionStatusCallback = new Session.StatusCallback() { @Override public void call(Session session, SessionState state, Exception exception) { onSessionStateChange(session, state, exception); } }; // login button login = (Button) findViewById(R.id.loginButton); login.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { login.setVisibility(View.GONE); connectToFB(); logout.setVisibility(View.VISIBLE); publishButton.setVisibility(View.VISIBLE); } }); // logout button logout = (Button) findViewById(R.id.logoutButton); logout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (currentSession != null) { currentSession.closeAndClearTokenInformation(); logout.setVisibility(View.GONE); publishButton.setVisibility(View.GONE); login.setVisibility(View.VISIBLE); } } }); // publish button publishButton = (Button) findViewById(R.id.publishButton); publishButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { publishStory(); } }); } /** * Connects the user to facebook */ public void connectToFB() { List<String> permissions = new ArrayList<String>(); permissions.add("publish_stream"); currentSession = new Session.Builder(this).build(); currentSession.addCallback(sessionStatusCallback); Session.OpenRequest openRequest = new Session.OpenRequest( MainActivity.this); openRequest.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO); openRequest.setRequestCode(Session.DEFAULT_AUTHORIZE_ACTIVITY_CODE); openRequest.setPermissions(permissions); currentSession.openForPublish(openRequest); } /** * this method is used by the facebook API */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (currentSession != null) { currentSession .onActivityResult(this, requestCode, resultCode, data); } } /** * manages the session state change. This method is called after the * <code>connectToFB</code> method. * * @param session * @param state * @param exception */ private void onSessionStateChange(Session session, SessionState state, Exception exception) { if (session != currentSession) { return; } if (state.isOpened()) { // Log in just happened. Toast.makeText(getApplicationContext(), "session opened", Toast.LENGTH_SHORT).show(); } else if (state.isClosed()) { // Log out just happened. Update the UI. Toast.makeText(getApplicationContext(), "session closed", Toast.LENGTH_SHORT).show(); } } /** * Publishes story on the logged user's wall */ public void publishStory() { Bundle params = new Bundle(); params.putString("name", "test-name"); params.putString("caption", "test-caption"); params.putString("description", "test-description"); params.putString("link", "http://curious-blog.blogspot.com"); params.putString("picture", "http://somewebsite/test.jpg"); WebDialog feedDialog = (new WebDialog.FeedDialogBuilder(this, currentSession, params)) .setOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(Bundle values, FacebookException error) { if (error == null) { // When the story is posted, echo the success // and the post Id. final String postId = values.getString("post_id"); if (postId != null) { // do some stuff } else { // User clicked the Cancel button Toast.makeText(getApplicationContext(), "Publish cancelled", Toast.LENGTH_SHORT) .show(); } } else if (error instanceof FacebookOperationCanceledException) { // User clicked the "x" button Toast.makeText(getApplicationContext(), "Publish cancelled", Toast.LENGTH_SHORT) .show(); } else { // Generic, ex: network error Toast.makeText(getApplicationContext(), "Error posting story", Toast.LENGTH_SHORT) .show(); } } }).setFrom("").build(); feedDialog.show(); } }
Your final activity_main.xml should look like this:
<LinearLayout 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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:id="@+id/loginButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login" /> <Button android:id="@+id/logoutButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Logout" android:visibility="gone" /> <Button android:id="@+id/publishButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Publish on my wall" android:visibility="gone"/> </LinearLayout>
Nice Post Easy to understand
ReplyDeletevery nice, Thank full to you
ReplyDeleteAbout logout. In my case, when I go out (logout) and come in soon after it retrieves the previous session. it not redirects me to the login screen. what you think about this?
ReplyDelete(I'm using closeAndClearTokenInformation() for logout)
Maybe you should check if you are using single sign on, on facebook. Check the connectToFb() method from the code above, and see if you have added the login behaviour:
DeleteopenRequest.setLoginBehaviour(SessionLoginBehavior.SUPPRESS_SSO);
Also if the above is not the problem, make sure that you are calling closeAndClearTokenInformation() on the active session object.
If this is not the case, post some code so we can look in to it.
My logout and publish button overlap and I am getting Api 100 error when I press on this overlapped button. Err: picture url is not formatted properly
ReplyDeleteAdd code snippet to inspect
Deletehow can I logout in other class?
ReplyDeleteIn the activity where you want to logout the user just write the code below:
DeleteSession session = Session.getActiveSession;
session.closeAndClearTokenInformation();
Excellent code ^^
ReplyDeletebut how to get user info from this example?
THANK YOU~
Let's assume we have two views in our activity TextView for the name of the user and ProfilePictureView for the profile picture of the user. Yout can define the ProfilePictureView in to your layout like this:
DeleteOPENTAG
//com.facebook.widget.ProfilePictureView
// android:id="@+id/selection_profile_pic"
// android:layout_width="58dp"
// android:layout_height="58dp"
// android:layout_marginLeft="24dp"
// android:layout_marginTop="24dp"
CLOSETAG
You can call this from the activity as:
ProfilePictureView profilePictureView = (ProfilePictureView) findViewById(R.id.selection_profile_pic);
Ok, that was for the picture.Next you will have to create a method makeMeRequest(final Session session), that will recive the current session:
private void makeMeRequest(final Session session) {
// Make an API call to get user data and define a
// new callback to handle the response.
Request request = Request.newMeRequest(session,
new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user, Response response) {
// If the response is successful
if (session == currentSession) {
if (user != null) {
Session.setActiveSession(currentSession);
// Set the id for the ProfilePictureView
// view that in turn displays the profile
// picture.
profilePictureView.setProfileId(user.getId());
// Set the Textview's text to the user's name.
userNameView.setText(user.getName());
}
}
if (response.getError() != null) {
// Handle errors, will do so later.
}
}
});
request.executeAsync();
}
Here in the method above you can see the "user" object right.If you want additional info from your user, you can call something like user.getBirthday(), user.getFirstName() etc.
So now that we have the makeMeRequest() method, you will have to call it from onSessionStateChange() method , where you check if the session is open, after
state.isOpen :
if(state.IsOpen(){
makeMeRequest(currentSession);
}
Hope this helps
ThanQ Very Much Boss
ReplyDeleteOn login my app crashes and I get this error. Any idea why this might be happening.
ReplyDelete(server)' ~ Channel is unrecoverably broken and will be disposed!
Are you testing the app on the emulator or on a device. Also if you can provide some more info, so we can see when this error occurs.
Deletenice work ..thanks a lot dude..
ReplyDeleteThanks a lot dude..
ReplyDeleteYou save my day :3
Thanks a lot for this tutoriel
ReplyDeleteHello, this is John. working in a custom facebook application developing company. Your post is very interesting
ReplyDeletei am already login with facebook ,so after opening this app , the session has to check i am logged in or not and if yes then i should not get login page
ReplyDeletehey how can I use this session in anothert activity? In my logibactivity I logging him yo my system, but in the mainactvity I need to send post status, But I cant do this, dou you know any way for this?
ReplyDelete