package com.gt.snssharinglibrary.service.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import com.facebook.FacebookAuthorizationException; import com.facebook.FacebookException; import com.facebook.FacebookOperationCanceledException; import com.facebook.FacebookRequestError; import com.facebook.LoggingBehavior; import com.facebook.Request; import com.facebook.Request.GraphUserListCallback; import com.facebook.Response; import com.facebook.Session; import com.facebook.Session.NewPermissionsRequest; import com.facebook.Session.OpenRequest; import com.facebook.SessionDefaultAudience; import com.facebook.SessionLoginBehavior; import com.facebook.SessionState; import com.facebook.Settings; import com.facebook.model.GraphUser; import com.facebook.widget.WebDialog; import com.facebook.widget.WebDialog.OnCompleteListener; import com.gt.snssharinglibrary.Config; import com.gt.snssharinglibrary.Config.SHARING_TYPE; import com.gt.snssharinglibrary.Constants; import com.gt.snssharinglibrary.pojo.CusProgressDialog; import com.gt.snssharinglibrary.pojo.SNSShareDetail; import com.gt.snssharinglibrary.service.SNSService; import com.gt.snssharinglibrary.service.SNSServiceCallback; import com.gt.snssharinglibrary.service.SNSServiceImpl.SNS_LOGIN_TYPE; import com.gt.snssharinglibrary.service.facebook_2_0.FacebookSessionStore; import com.gt.snssharinglibrary.util.LogController; import com.gt.snssharinglibrary.util.StringUtil; import com.gt.snssharinglibrary.util.Util; public class FacebookService30Impl extends SNSServiceSuperImpl implements SNSService { private enum STATUS_CALLBACK_TYPE { RESTORE, LOGIN, LOGOUT, POST } private enum PendingAction { NONE, POST_PHOTO, POST_STATUS_UPDATE } private SessionStatusCallback statusRestoreCallback; private SessionStatusCallback statusLoginCallback; private SNSServiceCallback snsServiceCallback; private PendingAction pendingAction = PendingAction.NONE; private SNSShareDetail pendingSNSShareDetail; private CusProgressDialog cusProgressDialog; // TODO Facebook APIs > Graph API > User > // https://developers.facebook.com/docs/reference/api/user/ private List<String> permissionsForRead = Arrays.asList(Config.FACEBOOK_PERMISSIONS); private OpenRequest genNewOpenForReadRequest(Activity activity, SessionStatusCallback callback) { return new OpenRequest(activity)// .setPermissions(permissionsForRead)// .setCallback(callback)// .setDefaultAudience(SessionDefaultAudience.FRIENDS)// .setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK); } @Override public void loadConfig() { // TODO Auto-generated method stub } @Override public void setSNSServiceCallback(SNSServiceCallback snsServiceCallback) { this.snsServiceCallback = snsServiceCallback; } @Override public boolean isLogged(Context context) { Session session = Session.getActiveSession(); if (session != null) { try { if (session.isOpened()) { return true; } } catch (Exception e) { } } return false; } @Override public void login(Activity activity, Handler handler, SNS_LOGIN_TYPE snsLoginType) { statusLoginCallback = new SessionStatusCallback(activity, STATUS_CALLBACK_TYPE.LOGIN); Session session = Session.getActiveSession(); if (!session.isOpened() && !session.isClosed()) { session.openForRead(genNewOpenForReadRequest(activity, statusLoginCallback)); } else { Session.openActiveSession(activity, true, statusLoginCallback); } } @Override public void logout(Activity activity, Handler handler) { Session session = Session.getActiveSession(); if (!session.isClosed()) { session.closeAndClearTokenInformation(); } loggoutStatus(activity, true, null); } @Override public void logginStatus(Context context, boolean isSuccessLogin, Object errorObject) { if (isSuccessLogin) { Session session = Session.getActiveSession(); if (session != null) { FacebookSessionStore.save(session, context); } getProfile(context); } if (snsServiceCallback != null) { snsServiceCallback.logginStatus(Constants.FACEBOOK_CODE, isSuccessLogin, errorObject); } } @Override public void loggoutStatus(Context context, boolean isSuccessLogout, Object errorObject) { if (isSuccessLogout) { Util.clearCookies(context); } if (snsServiceCallback != null) { snsServiceCallback.loggoutStatus(Constants.FACEBOOK_CODE, isSuccessLogout, errorObject); } } @Override public void post(Context context, SNSShareDetail snsShareDetail) { pendingAction = PendingAction.POST_STATUS_UPDATE; Session session = Session.getActiveSession(); if (session != null) { pendingSNSShareDetail = snsShareDetail; if (hasPublishPermission()) { handlePendingAction(context); } else { requestPublishPermission(context, session); } } } @Override public void postStatus(boolean isSuccessPost, Object errorObject) { if (snsServiceCallback != null) { snsServiceCallback.postStatus(Constants.FACEBOOK_CODE, isSuccessPost, errorObject); } } @Override public void getProfile(final Context context) { Session session = Session.getActiveSession(); if (session != null) { if (session.isOpened()) { // make request to the /me API Request request = Request.newMeRequest(session, new Request.GraphUserCallback() { // callback after Graph API response with user object @Override public void onCompleted(GraphUser user, Response response) { if (user != null) { // TextView etName = (TextView) // findViewById(R.id.etName); // etName.setText(user.getName() + "," + // user.getUsername() + "," + user.getId() + "," + // user.getLink() + "," + user.getFirstName() + // user.asMap().get("email")); String username = user.getUsername(); String facebookId = user.getId(); String email = null; String gender = null; try { email = user.asMap().get("email").toString(); } catch (Exception e) { } try { gender = user.asMap().get("gender").toString(); } catch (Exception e) { } FacebookSessionStore.saveFacebookInfo(username, facebookId, email, context); FacebookSessionStore.saveFacebookGender(context, gender); FacebookSessionStore.saveFacebookFirstName(context, user.getFirstName()); FacebookSessionStore.saveFacebookMiddleName(context, user.getMiddleName()); FacebookSessionStore.saveFacebookLastName(context, user.getLastName()); FacebookSessionStore.saveFacebookBirthday(context, user.getBirthday()); getProfileStatus(context, true, null); } else { getProfileStatus(context, false, null); } } }); Request.executeBatchAsync(request); } } } @Override public void getProfileStatus(final Context context, boolean isSuccessGetProfile, Object errorObject) { if (snsServiceCallback != null) { snsServiceCallback.getProfileStatus(Constants.FACEBOOK_CODE, isSuccessGetProfile, null); } if (Config.REQUEST_NEW_PREMISSION_AFTER_GET_PROFILE) { Session session = Session.getActiveSession(); requestPublishPermission(context, session); } } @Override public void onCreate(Activity activity, Bundle savedInstanceState) { Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS); Session session = Session.getActiveSession(); if (session == null) { statusRestoreCallback = new SessionStatusCallback(activity, STATUS_CALLBACK_TYPE.RESTORE); if (savedInstanceState != null) { session = Session.restoreSession(activity, null, statusRestoreCallback, savedInstanceState); } if (session == null) { session = new Session(activity); } Session.setActiveSession(session); if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) { session.openForRead(genNewOpenForReadRequest(activity, statusRestoreCallback)); } } } @Override public void onStart() { if (statusRestoreCallback != null) { Session.getActiveSession().addCallback(statusRestoreCallback); } } @Override public void onStop() { if (statusRestoreCallback != null) { Session.getActiveSession().removeCallback(statusRestoreCallback); } } @Override public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { Session.getActiveSession().onActivityResult(activity, requestCode, resultCode, data); } @Override public void onSaveInstanceState(Bundle outState) { Session session = Session.getActiveSession(); Session.saveSession(session, outState); } private class SessionStatusCallback implements Session.StatusCallback { private Context context; private STATUS_CALLBACK_TYPE statusCallbackType; private boolean deprecated = false; public SessionStatusCallback(Context context, STATUS_CALLBACK_TYPE statusCallbackType) { this.context = context; this.statusCallbackType = statusCallbackType; } public void setDeprecated() { this.deprecated = true; } @Override public void call(Session session, SessionState state, Exception exception) { if (deprecated) { return; } if (statusCallbackType.equals(STATUS_CALLBACK_TYPE.LOGIN)) { if (session != null) { if (session.isOpened()) { if (session.getAccessToken() != null) { if (session.getAccessToken().trim().length() > 0) { logginStatus(context, true, null); return; } } } } logginStatus(context, false, null); } else { onSessionStateChange(context, session, state, exception); } } } private boolean hasPublishPermission() { if (Config.facebook30SharingType.equals(SHARING_TYPE.WEB_DIALOG)) { return true; } if (Config.facebook30SharingType.equals(SHARING_TYPE.PLAIN_TEXT)) { Session session = Session.getActiveSession(); return session != null && session.getPermissions().contains("publish_actions"); } return false; } private void onSessionStateChange(Context context, Session session, SessionState state, Exception exception) { if (!(exception instanceof FacebookOperationCanceledException) && !(exception instanceof FacebookAuthorizationException) && state == SessionState.OPENED_TOKEN_UPDATED) { handlePendingAction(context); } else { pendingSNSShareDetail = null; } } @SuppressWarnings("incomplete-switch") private void handlePendingAction(Context context) { 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_PHOTO: // postPhoto(); break; case POST_STATUS_UPDATE: postStatusUpdate(context, pendingSNSShareDetail); break; } } private void postStatusUpdate(Context context, SNSShareDetail snsShareDetail) { if (hasPublishPermission() && snsShareDetail != null) { Session session = Session.getActiveSession(); if (Config.facebook30SharingType.equals(SHARING_TYPE.WEB_DIALOG)) { WebDialog.FeedDialogBuilder feedDialogBuilder = new WebDialog.FeedDialogBuilder(context, session); if (snsShareDetail.getTitle() != null) { feedDialogBuilder.setName(snsShareDetail.getTitle()); } if (snsShareDetail.getCaption() != null) { feedDialogBuilder.setCaption(snsShareDetail.getCaption()); } if (snsShareDetail.getDescription() != null) { feedDialogBuilder.setDescription(snsShareDetail.getDescription()); } if (snsShareDetail.getPictureLink() != null) { feedDialogBuilder.setPicture(snsShareDetail.getPictureLink()); } if (snsShareDetail.getLink() != null) { feedDialogBuilder.setLink(snsShareDetail.getLink()); } if (snsShareDetail.getFriendId() != null) { feedDialogBuilder.setTo(snsShareDetail.getFriendId()); } feedDialogBuilder.setOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(Bundle values, FacebookException error) { if (error == null) { String postId = values.getString("post_id"); if (postId != null) { postStatus(true, null); } else { postStatus(false, null); } } else { // title = getString(R.string.error); // alertMessage = error.getErrorMessage(); postStatus(false, error); } if (cusProgressDialog != null) { cusProgressDialog.dismiss(); } } }); feedDialogBuilder.build().show(); } else if (Config.facebook30SharingType.equals(SHARING_TYPE.PLAIN_TEXT)) { String message = snsShareDetail.getDescription(); if (message != null) { Request request = Request.newStatusUpdateRequest(session, message, new Request.Callback() { @Override public void onCompleted(Response response) { // GraphObject result = response.getGraphObject(); FacebookRequestError error = response.getError(); if (error == null) { postStatus(true, null); } else { // title = getString(R.string.error); // alertMessage = error.getErrorMessage(); postStatus(false, error); } if (cusProgressDialog != null) { cusProgressDialog.dismiss(); } } }); request.executeAsync(); } } /* * cusProgressDialog = new CusProgressDialog(context); * cusProgressDialog * .setMessage(StringMapping.FACEBOOK_POST_LOADING_MESSAGE); * cusProgressDialog.show(); * * Session session = Session.getActiveSession(); * * Bundle bundle = new Bundle(); * * if (snsShareDetail.getTitle() != null) { bundle.putString("name", * snsShareDetail.getTitle()); } * * if (snsShareDetail.getCaption() != null) { * bundle.putString("caption", snsShareDetail.getCaption()); } * * if (snsShareDetail.getDescription() != null) { * bundle.putString("description", snsShareDetail.getDescription()); * } * * if (snsShareDetail.getPictureLink() != null) { * bundle.putString("picture", snsShareDetail.getPictureLink()); } * * if (snsShareDetail.getLink() != null) { bundle.putString("link", * snsShareDetail.getLink()); } * * if (snsShareDetail.getFriendId() != null) { * bundle.putString("to", snsShareDetail.getFriendId()); } * * Request request = new Request(Session.getActiveSession(), * "me/feed", bundle, HttpMethod.POST, new Callback() { * * @Override public void onCompleted(Response response) { * FacebookRequestError error = response.getError(); * * if (error == null) { postStatus(true, null); } else { // title = * getString(R.string.error); // alertMessage = * error.getErrorMessage(); postStatus(false, error); } * * if(cusProgressDialog != null) { cusProgressDialog.dismiss(); } } * }); * * RequestAsyncTask task = new RequestAsyncTask(request); * task.execute(); */ } else { pendingAction = PendingAction.POST_STATUS_UPDATE; } pendingSNSShareDetail = null; } private void requestPublishPermission(Context context, Session session) { if (session != null && context instanceof Activity) { if (statusLoginCallback != null) { statusLoginCallback.setDeprecated(); } List<String> permissions = new ArrayList<String>(); permissions.add("publish_stream"); NewPermissionsRequest newPermissionsRequest = new NewPermissionsRequest((Activity) context, permissions); session.requestNewPublishPermissions(newPermissionsRequest); } } @Override public void getFriends(int photoWidth, int photoHeight) { Session activeSession = Session.getActiveSession(); if (activeSession.getState().isOpened()) { Request friendRequest = Request.newMyFriendsRequest(activeSession, new GraphUserListCallback() { @Override public void onCompleted(List<GraphUser> users, Response response) { LogController.log("INFO >>> " + response.toString()); if (users != null) { getFriendsStatus(true, users, null); } else { getFriendsStatus(false, null, null); } } }); Bundle params = new Bundle(); if (photoWidth <= 0 && photoHeight <= 0) { params.putString("fields", "id, name, installed, picture"); } else { params.putString("fields", "id, name, installed, picture.height(" + photoWidth + ").width(" + photoHeight + ")"); } friendRequest.setParameters(params); friendRequest.executeAsync(); } } @Override public void getFriendsStatus(boolean isSuccessGetFriends, Object friendsResultObject, Object errorObject) { if (snsServiceCallback != null) { snsServiceCallback.getFriendsStatus(isSuccessGetFriends, friendsResultObject, errorObject); } } @Override public void getFeeds() { Session activeSession = Session.getActiveSession(); if (activeSession.getState().isOpened()) { Request request = Request.newGraphPathRequest(activeSession, Config.FACEBOOK_FEEDER_ID + "/feed", new Request.Callback() { @Override public void onCompleted(Response response) { getFeedsStatus(true, response.getGraphObject().getInnerJSONObject(), null); } }); request.executeAsync(); } } @Override public void getFeedsStatus(boolean isSuccess, Object feedsResultObject, Object errorObject) { if (snsServiceCallback != null) { snsServiceCallback.getFeedsStatus(isSuccess, feedsResultObject, errorObject); } } @Override public void likeFeed(String feedId) { if (!StringUtil.isStringEmpty(feedId)) { Session activeSession = Session.getActiveSession(); if (activeSession.getState().isOpened()) { Request request = Request.newGraphPathRequest(activeSession, feedId + "/likes", new Request.Callback() { @Override public void onCompleted(Response response) { likeFeedStatus(true, response.getGraphObject().getInnerJSONObject(), ""); } }); request.executeAsync(); } } else { likeFeedStatus(false, "feedId: " + feedId, ""); } } @Override public void likeFeedStatus(boolean isSuccess, Object feedsResultObject, Object errorObject) { if (snsServiceCallback != null) { snsServiceCallback.likeFeedStatus(isSuccess, feedsResultObject, errorObject); } } @Override public void openPageByWebView(Activity activity, String link) { if (activity != null && !StringUtil.isStringEmpty(link)) { Uri uri = Uri.parse(link); Intent intent = new Intent(Intent.ACTION_VIEW, uri); activity.startActivity(intent); } } }