Now we will define some utility functions which we will use later, These functions help in updating the UI on clicking Login , Post Status and Post Photo Buttons.
Paste the following code in the LoginActivity
after closing brackets of onCreate()
Method
private void updateUI() {
boolean enableButtons = AccessToken.getCurrentAccessToken() != null;
postStatusUpdateButton.setEnabled(enableButtons || canPresentShareDialog);
postPhotoButton.setEnabled(enableButtons || canPresentShareDialogWithPhotos);
Profile profile = Profile.getCurrentProfile();
if (enableButtons && profile != null) {
new LoadProfileImage(profilePicImageView).execute(profile.getProfilePictureUri(200, 200).toString());
greeting.setText(getString(R.string.hello_user, profile.getFirstName()));
postingEnabled = true;
postPhotoButton.setVisibility(View.VISIBLE);
postStatusUpdateButton.setVisibility(View.VISIBLE);
getUserInterests.setVisibility(View.VISIBLE);
} else {
Bitmap icon = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_default);
profilePicImageView.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(), icon, 200, 200, 200, false, false, false, false));
greeting.setText(null);
postingEnabled = false;
postPhotoButton.setVisibility(View.GONE);
postStatusUpdateButton.setVisibility(View.GONE);
getUserInterests.setVisibility(View.GONE);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
}
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
pendingAction = PendingAction.NONE;
switch (previouslyPendingAction) {
case NONE:
break;
case POST_PHOTO:
postPhoto();
break;
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
}
}
private void onClickPostStatusUpdate() {
performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog);
}
private void postStatusUpdate() {
Profile profile = Profile.getCurrentProfile();
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle("Integrate Facebook Login to your Android App")
.setContentDescription(
"This app shows how to integrate Facebook Login to your Android App")
.setContentUrl(Uri.parse("http://www.androidtutorialpoint.com/material-design/adding-facebook-login-to-android-app/"))
.build();
if (canPresentShareDialog) {
shareDialog.show(linkContent);
} else if (profile != null && hasPublishPermission()) {
ShareApi.share(linkContent, shareCallback);
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}
private void onClickPostPhoto() {
performPublish(PendingAction.POST_PHOTO, canPresentShareDialogWithPhotos);
}
private void postPhoto() {
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.androidlogo);
SharePhoto sharePhoto = new SharePhoto.Builder().setBitmap(image).build();
ArrayList<SharePhoto> photos = new ArrayList<>();
photos.add(sharePhoto);
SharePhotoContent sharePhotoContent =
new SharePhotoContent.Builder().setPhotos(photos).build();
if (canPresentShareDialogWithPhotos) {
shareDialog.show(sharePhotoContent);
} else if (hasPublishPermission()) {
ShareApi.share(sharePhotoContent, shareCallback);
} else {
pendingAction = PendingAction.POST_PHOTO;
LoginManager.getInstance().logInWithPublishPermissions(
this,
Arrays.asList(PERMISSION));
}
}
private boolean hasPublishPermission() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
return accessToken != null && accessToken.getPermissions().contains("publish_actions");
}
private void performPublish(PendingAction action, boolean allowNoToken) {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null || allowNoToken) {
pendingAction = action;
handlePendingAction();
}
}
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... uri) {
String url = uri[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if (result != null) {
Bitmap resized = Bitmap.createScaledBitmap(result,200,200, true);
bmImage.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),resized,250,200,200, false, false, false, false));
}
}
}
Let’s Discuss all the helper methods we have added.
The complete FacebookFragment.java code is shown below:
Faceboook Fragment
package com.androidtutorialpoint.flogin;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookAuthorizationException;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.Profile;
import com.facebook.ProfileTracker;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.facebook.share.ShareApi;
import com.facebook.share.Sharer;
import com.facebook.share.model.ShareLinkContent;
import com.facebook.share.model.SharePhoto;
import com.facebook.share.model.SharePhotoContent;
import com.facebook.share.widget.ShareDialog;
import org.json.JSONObject;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
public class FacebookFragment extends Fragment{
private LoginButton loginButton;
private Button getUserInterests;
private boolean postingEnabled = false;
private static final String PERMISSION = "publish_actions";
private final String PENDING_ACTION_BUNDLE_KEY =
"com.example.hellofacebook:PendingAction";
private Button postStatusUpdateButton;
private Button postPhotoButton;
private ImageView profilePicImageView;
private TextView greeting;
private PendingAction pendingAction = PendingAction.NONE;
private boolean canPresentShareDialog;
private boolean canPresentShareDialogWithPhotos;
private CallbackManager callbackManager;
private ProfileTracker profileTracker;
private ShareDialog shareDialog;
private FacebookCallback<Sharer.Result> shareCallback = new FacebookCallback<Sharer.Result>() {
@Override
public void onCancel() {
Log.d("FacebookFragment", "Canceled");
}
@Override
public void onError(FacebookException error) {
Log.d("FacebookFragment", String.format("Error: %s", error.toString()));
String title = getString(R.string.error);
String alertMessage = error.getMessage();
showResult(title, alertMessage);
}
@Override
public void onSuccess(Sharer.Result result) {
Log.d("FacebookFragment", "Success!");
if (result.getPostId() != null) {
String title = getString(R.string.success);
String id = result.getPostId();
String alertMessage = getString(R.string.successfully_posted_post, id);
showResult(title, alertMessage);
}
}
private void showResult(String title, String alertMessage) {
new AlertDialog.Builder(getActivity())
.setTitle(title)
.setMessage(alertMessage)
.setPositiveButton(R.string.ok, null)
.show();
}
};
private enum PendingAction {
NONE,
POST_PHOTO,
POST_STATUS_UPDATE
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity());
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_facebook, parent, false);
loginButton = (LoginButton) v.findViewById(R.id.loginButton);
loginButton.setFragment(this);
callbackManager = CallbackManager.Factory.create();
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Toast toast = Toast.makeText(getActivity(), "Logged In", Toast.LENGTH_SHORT);
postingEnabled = true;
postPhotoButton.setVisibility(View.VISIBLE);
postStatusUpdateButton.setVisibility(View.VISIBLE);
getUserInterests.setVisibility(View.VISIBLE);
toast.show();
handlePendingAction();
updateUI();
}
@Override
public void onCancel() {
if (pendingAction != PendingAction.NONE) {
showAlert();
pendingAction = PendingAction.NONE;
}
updateUI();
}
@Override
public void onError(FacebookException exception) {
if (pendingAction != PendingAction.NONE
&& exception instanceof FacebookAuthorizationException) {
showAlert();
pendingAction = PendingAction.NONE;
}
updateUI();
}
private void showAlert() {
new AlertDialog.Builder(getActivity())
.setTitle(R.string.cancelled)
.setMessage(R.string.permission_not_granted)
.setPositiveButton(R.string.ok, null)
.show();
}
});
shareDialog = new ShareDialog(this);
shareDialog.registerCallback(
callbackManager,
shareCallback);
if (savedInstanceState != null) {
String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY);
pendingAction = PendingAction.valueOf(name);
}
profileTracker = new ProfileTracker() {
@Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
updateUI();
handlePendingAction();
}
};
profilePicImageView = (ImageView) v.findViewById(R.id.profilePicture);
greeting = (TextView) v.findViewById(R.id.greeting);
postStatusUpdateButton = (Button) v.findViewById(R.id.postStatusUpdateButton);
postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPostStatusUpdate();
}
});
postPhotoButton = (Button) v.findViewById(R.id.postPhotoButton);
postPhotoButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
onClickPostPhoto();
}
});
getUserInterests = (Button) v.findViewById(R.id.getInterestsButton);
getUserInterests.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(
JSONObject object,
GraphResponse response) {
if (object != null) {
Log.d("Flogin", object.toString());
ArrayList<String> favAthletes = JSONParser.getFavAthletes(object);
Log.d("Print",favAthletes.toString());
Toast t = Toast.makeText(getActivity(), object.toString(), Toast.LENGTH_LONG);
t.show();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,email,favorite_athletes,favorite_teams");
request.setParameters(parameters);
request.executeAsync();
}
});
canPresentShareDialog = ShareDialog.canShow(
ShareLinkContent.class);
canPresentShareDialogWithPhotos = ShareDialog.canShow(
SharePhotoContent.class);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LoginManager.getInstance().logInWithReadPermissions(getActivity(), Arrays.asList("public_profile"));
if(!postingEnabled) {
postingEnabled = true;
postPhotoButton.setVisibility(View.VISIBLE);
postStatusUpdateButton.setVisibility(View.VISIBLE);
getUserInterests.setVisibility(View.VISIBLE);
}else{
postingEnabled = false;
postPhotoButton.setVisibility(View.GONE);
postStatusUpdateButton.setVisibility(View.GONE);
getUserInterests.setVisibility(View.GONE);
}
}
});
return v;
}
@Override
public void onResume() {
super.onResume();
AppEventsLogger.activateApp(getActivity());
updateUI();
}
@Override
public void onPause() {
super.onPause();
AppEventsLogger.deactivateApp(getActivity());
}
@Override
public void onDestroy() {
super.onDestroy();
profileTracker.stopTracking();
}
private void updateUI() {
boolean enableButtons = AccessToken.getCurrentAccessToken() != null;
postStatusUpdateButton.setEnabled(enableButtons || canPresentShareDialog);
postPhotoButton.setEnabled(enableButtons || canPresentShareDialogWithPhotos);
Profile profile = Profile.getCurrentProfile();
if (enableButtons && profile != null) {
new LoadProfileImage(profilePicImageView).execute(profile.getProfilePictureUri(200, 200).toString());
greeting.setText(getString(R.string.hello_user, profile.getFirstName()));
} else {
Bitmap icon = BitmapFactory.decodeResource(getContext().getResources(),R.drawable.user_default);
profilePicImageView.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(), icon, 200, 200, 200, false, false, false, false));
greeting.setText(null);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(PENDING_ACTION_BUNDLE_KEY, pendingAction.name());
}
private void handlePendingAction() {
PendingAction previouslyPendingAction = pendingAction;
pendingAction = PendingAction.NONE;
switch (previouslyPendingAction) {
case NONE:
break;
case POST_PHOTO:
postPhoto();
break;
case POST_STATUS_UPDATE:
postStatusUpdate();
break;
}
}
private void onClickPostStatusUpdate() {
performPublish(PendingAction.POST_STATUS_UPDATE, canPresentShareDialog);
}
private void postStatusUpdate() {
Profile profile = Profile.getCurrentProfile();
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle("Integrate Facebook Login to your Android App")
.setContentDescription(
"This app shows how to integrate Facebook Login to your Android App")
.setContentUrl(Uri.parse("http://www.androidtutorialpoint.com/material-design/adding-facebook-login-to-android-app/"))
.build();
if (canPresentShareDialog) {
shareDialog.show(linkContent);
} else if (profile != null && hasPublishPermission()) {
ShareApi.share(linkContent, shareCallback);
} else {
pendingAction = PendingAction.POST_STATUS_UPDATE;
}
}
private void onClickPostPhoto() {
performPublish(PendingAction.POST_PHOTO, canPresentShareDialogWithPhotos);
}
private void postPhoto() {
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.androidlogo);
SharePhoto sharePhoto = new SharePhoto.Builder().setBitmap(image).build();
ArrayList<SharePhoto> photos = new ArrayList<>();
photos.add(sharePhoto);
SharePhotoContent sharePhotoContent =
new SharePhotoContent.Builder().setPhotos(photos).build();
if (canPresentShareDialogWithPhotos) {
shareDialog.show(sharePhotoContent);
} else if (hasPublishPermission()) {
ShareApi.share(sharePhotoContent, shareCallback);
} else {
pendingAction = PendingAction.POST_PHOTO;
LoginManager.getInstance().logInWithPublishPermissions(
this,
Arrays.asList(PERMISSION));
}
}
private boolean hasPublishPermission() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
return accessToken != null && accessToken.getPermissions().contains("publish_actions");
}
private void performPublish(PendingAction action, boolean allowNoToken) {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken != null || allowNoToken) {
pendingAction = action;
handlePendingAction();
}
}
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... uri) {
String url = uri[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
if (result != null) {
Bitmap resized = Bitmap.createScaledBitmap(result,200,200, true);
bmImage.setImageBitmap(ImageHelper.getRoundedCornerBitmap(getContext(),resized,250,200,200, false, false, false, false));
}
}
}
}
FacebookFragment will be hosted in the LoginActivity
. Open the layout file activity_login.xml and add the following code.
activity_login.xml
="1.0"="utf-8"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".LoginActivity">
</RelativeLayout>
The layout will act as container for the FacebookFragment. Next add the FragmentManager to LoginActivity in order to start the fragment.
LoginActivity
package com.androidtutorialpoint.flogin;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class LoginActivity extends AppCompatActivity {
private com.facebook.login.widget.LoginButton loginButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = new FacebookFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
We have used some utility classes like JSONParser
Create these two classes in the same package:
ImageHelper.java
package com.androidtutorialpoint.flogin;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
public class ImageHelper {
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
final float roundPx = pixels*densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
if (squareTL ){
canvas.drawRect(0, h/2, w/2, h, paint);
}
if (squareTR ){
canvas.drawRect(w/2, h/2, w, h, paint);
}
if (squareBL ){
canvas.drawRect(0, 0, w/2, h/2, paint);
}
if (squareBR ){
canvas.drawRect(w/2, 0, w, h/2, paint);
}
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, paint);
return output;
}
public static Bitmap getRoundedCornerBitmap1(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
JSONParser.java
package com.androidtutorialpoint.flogin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class JSONParser {
public static ArrayList<String> favAthletes = new ArrayList<>();
public static ArrayList<String> favTeams = new ArrayList<>();
public static ArrayList<String> getFavAthletes(JSONObject obj) {
favAthletes.clear();
try {
JSONArray arr = obj.getJSONArray("favorite_athletes");
String s;
for (int i = 0; i < arr.length(); i++) {
obj = arr.getJSONObject(i);
s = obj.getString("name");
favAthletes.add(s);
}
} catch (JSONException e) {
e.printStackTrace();
}
return favAthletes;
}
public static ArrayList<String> getFavTeams(JSONObject obj) {
favTeams.clear();
try {
JSONArray arr = obj.getJSONArray("favorite_teams");
String s;
for (int i = 0; i < arr.length(); i++) {
obj = arr.getJSONObject(i);
s = obj.getString("name");
favTeams.add(s);
}
} catch (JSONException e) {
e.printStackTrace();
}
return favTeams;
}
public static String getName(JSONObject obj) {
String s1 = "";
try {
s1 = obj.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
return s1;
}
public static String getId(JSONObject obj) {
String s1 = "";
try {
s1 = obj.getString("id");
} catch (JSONException e) {
e.printStackTrace();
}
return s1;
}
}
Additionally you can copy the strings.xml and dimens.xml files
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="button_width">250dp</dimen>
</resources>
<resources>
<string name="app_name">FLogin</string>
<string name ="facebook_app_id">148851038810437</string><string name="facebook_app_name">HelloFBSample</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">Post ID: %1$s</string>
<string name="error">Error</string>
<string name="status_update">Updating status for %1$s at %2$s</string>
<string name="photo_post">Photo Post</string>
<string name="you_picked">You picked:</string>
<string name="no_friends_selected"><No friends selected></string>
<string name="no_place_selected"><No place selected></string>
<string name="pick_seattle_place">Pick a Seattle Place</string>
<string name="app_id">355198514515820</string>
<string name="exception">Exception: %1$s</string>
</resources>
You can add the image resources used in the project, by downloading the project from Download Now button at the top of the post and copying the images from the drawable’s folder.
Now, run the app on your phone or emulator where you are already using your Facebook account, and you should be able to sign in to the App using your existing Facebook account. Please note that while your app is in development stage you can login into the app using the facebook account which is registered as Developer or a Tester. Otherwise you will get the following error “App Not Setup: This app is still in development mode, and you don’t have access to it. Switch to a registered test user or ask an app admin for permissions.”
In case you face similar issue, then configure the roles in the Facebook Developers page in the app roles section.
What’s Next!!!
You can experiment with different user permissions and try to access the information from the user.