How to implement Facebook Login on Android

Sign in with Social Networks is great way of achieving user details that helps in registration process. I have already showed you How to Sign in with Google Plus.  Now Lets see how to implement Facebook Login on your application. We can access Facebook API using Facebook SDK for doing many tasks such as posting status, posting photos,getting email etc.

So, Lets start with the tutorial!

UPDATE: This tutorial might not work now. I have created an updated tutorial with the latest SDK.

Prerequisites

  • A Device or emulator that has Facebook app installed (If the device did not have Facebook installed, it will just use dialog box for authentication purposes)
  • Download Facebook SDK (I am using v3.14)
  • Create a Facebook App

1. Setting Up Facebook Application

We need to create a Facebook application to access Facebook API. Follow these steps:

1. Go to https://developers.facebook.com/ and Sign Yourself as Developer. Note that it needs Mobile verification for registration as developer.

2. On the top bar, go to ‘Apps‘ > ‘Create a New App‘:

Screenshot_7

3. Enter basic information such as its name and a unique namespace:

Screenshot_1

4. 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.

Screenshot_8

 

2. Downloading and Importing Facebook SDK

1. Download Facebook SDK and extract it.

2. Launch Eclipse. Select File > Import > Android > Existing Android Code Into Workspace and click Next.

3.  Select Browse…. Locate the downloaded SDK. Deselect all the samples since they are not necessary.

Screenshot_3

Note: Make sure that you check “Copy projects into workspace” as It is necessary that the android application project and the library must be in same workspace.

3.  Creating and Configure Android Application Project

1. Create New application project : File  > New > Android Application  Project. Set min SDK to 2.3 API and max SDK to latest version.

2. Right click on the project > Properties. In the dialog window, Select Android from the left. Click on Add button under library section. Add Facebook SDK and click on OK

Screenshot_9

Note: Don’t panic about the appcompat library, it just comes with every android project you build with the latest version of eclipse juno. It is not necessary for this project.

3. Optional: Click Project > Clean to ensure your project picks up the settings.

4. Open your AndroidManifest.xml file.  Add these permissions and meta data to declare the app_id of your facebook application.

 Permissions:

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

Activity and Meta Data:

 <activity android:name="com.facebook.LoginActivity"                   android:theme="@android:style/Theme.Translucent.NoTitleBar"                   android:label="@string/app_name" />
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/> 

Complete AndroidManifest.xml:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.labs.binarywall.facebooklogin"     android:versionCode="1"     android:versionName="1.0" >

    <uses-sdk         android:minSdkVersion="8"         android:targetSdkVersion="21" />
<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" >
        <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:theme="@android:style/Theme.Translucent.NoTitleBar"                   android:label="@string/app_name" />
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id"/>
       
    </application>

</manifest>

As you can see,we have store app_id value in the strings.xml. Therefore, we need to update our strings.xml file. Go to res => values => strings.xml

 <?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">facebooklogin</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="app_id">693658354003345</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">Facebook Android Login Test: Updating status for %1$s at %2$s</string>
</resources>

5. Now, lets look out at the design layout i.e. activity_main.xml file :


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     xmlns:facebook="http://schemas.android.com/apk/res-auto"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical">

    <com.facebook.widget.LoginButton         android:id="@+id/authButton"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center_horizontal"         android:layout_marginTop="30dp"         />
<LinearLayout         android:id="@+id/pro_layout"         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:layout_margin="20dp"         android:orientation="vertical"         android:weightSum="3"         >
    <com.facebook.widget.ProfilePictureView                     android:id="@+id/profilePicture"                     android:layout_height="wrap_content"                     android:layout_width="wrap_content"                     android:layout_gravity="center"                     android:layout_marginBottom="10dp"                     facebook:preset_size="large"                     android:visibility="gone"/>
        
        <TextView                 android:id="@+id/pro_Name"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_gravity="center"                 android:padding="5dp"                 android:textSize="20dp"                 android:visibility="gone" />
 
            <TextView                 android:id="@+id/pro_Email"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_gravity="center"                 android:padding="5dp"                 android:textSize="18dp"                 android:visibility="gone"/>
            
            
          <Button         android:id="@+id/btnpostStatus"         style="@style/ButtonText"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_centerHorizontal="true"         android:layout_margin="4dp"         android:layout_marginTop="72dp"         android:background="@drawable/layers_fb_button_bg"         android:paddingBottom="10dp"         android:paddingLeft="30dp"         android:paddingRight="10dp"         android:paddingTop="10dp"        android:visibility="gone"         android:text="Post Status" />
            </LinearLayout>

</LinearLayout>

In this layout file, I have used Login button of Facebook by specifying the full class : com.facebook.widget.Loginbutton and for displaying profile picture, I have used com.facebook.widget.ProfilePictureView. The application will display name,email and picture of the user and a post status button for updating status.

The layout design will look this:

device-2014-07-16-222333

6. Now, lets setup a fragment to display this UI. The fragment will be hosted by the main activity so you’ll make some changes in the main activity class shortly to enable this.

Create a new class MainFragment.java that’s a subclass of the Fragment class. and override the OnCreateView() method to setup the layout


    @Override
    public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // TODO Auto-generated method stub
         View view = inflater.inflate(R.layout.activity_main, container, false);
        
         //login button and setting permissions
         LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
         authButton.setFragment(this);
         authButton.setReadPermissions(Arrays.asList("email"));
        
         //setting variables
         Name = (TextView) view.findViewById(R.id.pro_Name);
         Email = (TextView) view.findViewById(R.id.pro_Email);
         Pic = (ProfilePictureView) view.findViewById(R.id.profilePicture);
        
           postStatusUpdateButton = (Button) view.findViewById(R.id.btnpostStatus);
            postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    onClickPostStatusUpdate();
                }
            });
        
            return view;
    }

Once, Fragment is created. Go back to your MainActivity.java and set it up to use your fragment.

MainActivity.java file:

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends FragmentActivity {

    
    private MainFragment mainFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        
        if (savedInstanceState == null) {
            // Add the fragment on initial activity setup
            mainFragment = new MainFragment();
            getSupportFragmentManager()
            .beginTransaction()
            .add(android.R.id.content, mainFragment)
            .commit();
        } else {
            // Or set the fragment from restored state info
            mainFragment = (MainFragment) getSupportFragmentManager()
            .findFragmentById(android.R.id.content);
        }
        
      }
    }

 

Now define a private method that can control the UI in MainFragment.java. When the session state is open, you can display your authenticated UI, such as making a new button visible. When the state is closed, you can display the non-authenticated UI, such as hiding the new button.


    private void onSessionStateChange(Session session, SessionState state, Exception exception) {
        if (state.isOpened()) {
            Log.i(TAG, "Logged in...");
            Toast.makeText(getActivity(), "Logged in ", Toast.LENGTH_SHORT).show();
         // make request to the /me API
            Request.newMeRequest(session, new Request.GraphUserCallback() {
                // callback after Graph API response with user object
            @Override
            public void onCompleted(GraphUser user, Response response) {
                // TODO Auto-generated method stub
                
                if (user != null) {
                MainFragment.this.user = user;
                      UpdateUI(user);      
                    }
            }
            }).executeAsync();
        } else if (state.isClosed()) {
            Log.i(TAG, "Logged out...");
            Toast.makeText(getActivity(), "Logged Out ", Toast.LENGTH_SHORT).show();
            resetToDefaultUI();
        }
    }

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

To ensure that the sessions are set up correctly, your fragment must override the fragment lifecycle methods: onCreate(), onResume(), onPause(), onDestroy(), onActivityResult() and onSaveInstanceState()


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        uiHelper = new UiLifecycleHelper(getActivity(), callback);
        uiHelper.onCreate(savedInstanceState);
     

    }
    
    @Override
    public void onResume() {
        super.onResume();
        // For scenarios where the main activity is launched and user
        // session is not null, the session state change notification
        // may not be triggered. Trigger it if it's open/closed.
        Session session = Session.getActiveSession();
        if (session != null &&
               (session.isOpened() || session.isClosed()) ) {
            onSessionStateChange(session, session.getState(), null);
        }
        uiHelper.onResume();
    }

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

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

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

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        uiHelper.onSaveInstanceState(outState);
    }

For posting status, onClickPostStatusUpdate() is called. Then, It checks for publish_actions permissions. If it is true, it post the status and if it is false, it opens a new permissions request from the user.


//called when post status button is clicked
    private void onClickPostStatusUpdate() {
        Session session = Session.getActiveSession();
        if (session != null) {
            Log.i("intent", "check1");
           
            if (hasPublishPermission()) {
                // We can do the action right away.
                Log.i("intent", "Check2");
                postStatusUpdate();
                return;
            } else if (session.isOpened()) {
                // We need to get new permissions, then complete the action when we get called back.
                Session.NewPermissionsRequest newPermissionsRequest = new Session
                          .NewPermissionsRequest(this, Arrays.asList("publish_actions"));
                        session.requestNewPublishPermissions(newPermissionsRequest);
                return;
            }
        }

    }
    
    //called when we have publish_actions permissions i.e hasPublishPermission() returns true
    private void postStatusUpdate() {
         Log.i("called",user.getFirstName() + " " + hasPublishPermission() );
       if (user != null && hasPublishPermission()) {
           Log.i("called","chekc");
            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();
        }
    }
    
    //graphobject for getting user id
    private interface GraphObjectWithId extends GraphObject {
        String getId();
    }
    
    //Dialog box to display after posting successfully
    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(getActivity())
                .setTitle(title)
                .setMessage(alertMessage)
                .setPositiveButton(R.string.ok, null)
                .show();
    }
    
    //checking for publish permissions
      private boolean hasPublishPermission() {
            Session session = Session.getActiveSession();
            return session != null && session.getPermissions().contains("publish_actions");
        }

Note that As of latest Facebook SDK 3.14, you cannot directly ask user for publish_actions permissions while doing login. You need to separately ask user before posting the status. Also, While making this testing app, You cannot test post status method until you’re account that you are using for testing is registered as developer or tester in the Facebook application we created. For making this for all users, you need to submit your Facebook application for review.

3. Configuring Facebook App

Now, you will  need to associate your Android keys hashes with the app. The key hash is used by Facebook as a security check for authenticity. By default, the app’s package is signed with a machine specific debug key. When publishing the app it is typically signed with a different.

1. Go to ‘Settings‘ in the left nav, then click on the ‘Add Platform‘ button, and select Android.

Screenshot_5 Screenshot_6

2.  Now, You need to enter Key hash to communicate with Facebook API. It is generated using the keystore that we used for signing the app. In this case, we are using the default android debug key keystore. For generating keyhash, use the following command:

For windows:

 keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64 

For linux:

 keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64 

 

Screenshot_11

Note that You need to set environment variables for using keytool and openssl. Keytool comes with the JDK kit. If you are not familiar with the keytool and want to know How to use keytool, visit this link. For using openssl, you need to install it. Download OpenSSL from here.

Screenshot_10

Note that For some users, the above command didn’t work and show invalid keyhash. To get rid of this, there is full proof code for getting the Key Hash for android debug keystore. Just make sure to add this code in the MainActivity.java’s OnCreate() method:


//below code is used to getting the Key hash used in Facebook app dashboard
         try {
                PackageInfo info = getPackageManager().getPackageInfo(
                        "com.labs.binarywall.facebooklogin",
                        PackageManager.GET_SIGNATURES);
                for (Signature signature : info.signatures) {
                    MessageDigest md = MessageDigest.getInstance("SHA");
                    md.update(signature.toByteArray());
                    Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
                    }
            } catch (NameNotFoundException e) {

            } catch (NoSuchAlgorithmException e) {

            }

 

It will display the keyhash in the logcat output so that you can copy from there.

Screenshot_12

Also, Enter your package name and main activity class name and Click Save Changes.

Complete MainActivity.java:


package com.labs.binarywall.facebooklogin;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.ActionBarActivity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends FragmentActivity {

private MainFragment mainFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (savedInstanceState == null) {
// Add the fragment on initial activity setup
mainFragment = new MainFragment();
getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content, mainFragment)
.commit();
} else {
// Or set the fragment from restored state info
mainFragment = (MainFragment) getSupportFragmentManager()
.findFragmentById(android.R.id.content);
}

//below code is used to getting the Key hash used in Facebook app dashboard
try {
PackageInfo info = getPackageManager().getPackageInfo(
"com.labs.binarywall.facebooklogin",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (NameNotFoundException e) {

} catch (NoSuchAlgorithmException e) {

}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

Complete MainFragment.java:


package com.labs.binarywall.facebooklogin;

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

import com.facebook.FacebookRequestError;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphPlace;
import com.facebook.model.GraphUser;
import com.facebook.widget.LoginButton;
import com.facebook.widget.ProfilePictureView;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainFragment extends Fragment {
private static final String TAG = "MainFragment";
private UiLifecycleHelper uiHelper;
private TextView Name;
private TextView Email;
private ProfilePictureView Pic;

private GraphUser user;
private boolean canPresentShareDialog;
private GraphPlace place;
private List<GraphUser> tags;

private PendingAction pendingAction = PendingAction.NONE;
private Button postStatusUpdateButton;
private enum PendingAction {
NONE,
POST_STATUS_UPDATE
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.activity_main, container, false);

//login button and setting permissions
LoginButton authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setFragment(this);
authButton.setReadPermissions(Arrays.asList("email"));

//setting variables
Name = (TextView) view.findViewById(R.id.pro_Name);
Email = (TextView) view.findViewById(R.id.pro_Email);
Pic = (ProfilePictureView) view.findViewById(R.id.profilePicture);

postStatusUpdateButton = (Button) view.findViewById(R.id.btnpostStatus);
postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPostStatusUpdate();
}
});

return view;
}

private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
Toast.makeText(getActivity(), "Logged in ", Toast.LENGTH_SHORT).show();
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
@Override
public void onCompleted(GraphUser user, Response response) {
// TODO Auto-generated method stub

if (user != null) {
MainFragment.this.user = user;
UpdateUI(user);
}
}
}).executeAsync();
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
Toast.makeText(getActivity(), "Logged Out ", Toast.LENGTH_SHORT).show();
resetToDefaultUI();
}
}

private void resetToDefaultUI() {
// called when user logged out
Name.setVisibility(View.GONE);
Email.setVisibility(View.GONE);
Pic.setVisibility(View.GONE);
postStatusUpdateButton.setVisibility(View.GONE);
}

private void UpdateUI(GraphUser user) {
// called when user is authenticated
Name.setVisibility(View.VISIBLE);
Email.setVisibility(View.VISIBLE);
Pic.setVisibility(View.VISIBLE);
postStatusUpdateButton.setVisibility(View.VISIBLE);

Name.setText(user.getName());
Email.setText(user.getProperty("email").toString());
Pic.setProfileId(user.getId());

}

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

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);

}

@Override
public void onResume() {
super.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it's open/closed.
Session session = Session.getActiveSession();
if (session != null &&
(session.isOpened() || session.isClosed()) ) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}

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

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

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

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}

//called when post status button is clicked
private void onClickPostStatusUpdate() {
Session session = Session.getActiveSession();
if (session != null) {
Log.i("intent", "check1");

if (hasPublishPermission()) {
// We can do the action right away.
Log.i("intent", "Check2");
postStatusUpdate();
return;
} else if (session.isOpened()) {
// We need to get new permissions, then complete the action when we get called back.
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, Arrays.asList("publish_actions"));
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
}

}

//called when we have publish_actions permissions i.e hasPublishPermission() returns true
private void postStatusUpdate() {
Log.i("called",user.getFirstName() + " " + hasPublishPermission() );
if (user != null && hasPublishPermission()) {
Log.i("called","chekc");
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();
}
}

//graphobject for getting user id
private interface GraphObjectWithId extends GraphObject {
String getId();
}

//Dialog box to display after posting successfully
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(getActivity())
.setTitle(title)
.setMessage(alertMessage)
.setPositiveButton(R.string.ok, null)
.show();
}

//checking for publish permissions
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains("publish_actions");
}

}

App in Action

device-2014-07-17-212037

device-2014-07-16-222333

device-2014-07-16-222411

Screenshot_13

 Download Project Files

Download Project

 

 

  • Joel || GetAvenue

    The Only tutorial that helped, other tutorials are depreciated. Thanks