Session between different activity in Facebook android sdk - android

There are two activity in my app to handle the 1) login 2)share image (if not login , login first then share)
The problem is when I include all code in one activity it works. But when I put the login in a fragment , the share image in another activity, then the login is work , but the share image activity behave incorrectly (Ask me to login even it is logined , and will not trigger the share image action)
Login Fragment:
public class Home extends Fragment {
public View rootView;
public ImageView HomeBg;
public ImageView buttonLoginLogout;
public TextView chi;
public TextView eng;
public ColorStateList oldColor;
public SharedPreferences prefs;
//Facebook login
private Session.StatusCallback statusCallback = new SessionStatusCallback();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getActivity().getActionBar().hide();
rootView = inflater.inflate(R.layout.home, container, false);
buttonLoginLogout = (ImageView) rootView.findViewById(R.id.home_connectFB);
eng = (TextView) rootView.findViewById(R.id.btn_eng);
chi = (TextView) rootView.findViewById(R.id.btn_chi);
if (getActivity().getResources().getConfiguration().locale
.equals(Locale.TRADITIONAL_CHINESE)) {
chi.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
oldColor = eng.getTextColors();
} else {
eng.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
oldColor = chi.getTextColors();
}
eng.setOnClickListener(setChangeLangListener("en"));
chi.setOnClickListener(setChangeLangListener("zh"));
//Facebook login
Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
}
if (session == null) {
session = new Session(getActivity());
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
}
}
updateView();
return rootView;
}
#Override
public void onStart() {
super.onStart();
Session.getActiveSession().addCallback(statusCallback);
}
#Override
public void onStop() {
super.onStop();
Session.getActiveSession().removeCallback(statusCallback);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
private void updateView() {
Session session = Session.getActiveSession();
if (session.isOpened()) {
buttonLoginLogout.setImageResource(R.drawable.landing_btn_take_a_selfie);
buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
((LandingPage)getActivity()).tabHost.setCurrentTab(2);
}
});
} else {
buttonLoginLogout.setImageResource(R.drawable.landing_btn_connect_facebook);
buttonLoginLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { onClickLogin(); }
});
}
}
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(getActivity(), this, true, statusCallback);
}
}
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
updateView();
}
}
public OnClickListener setChangeLangListener(final String lang) {
OnClickListener changeLangListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
Configuration config = new Configuration(getResources()
.getConfiguration());
if (lang.equals("en")) {
config.locale = Locale.ENGLISH;
chi.setTextColor(oldColor);
eng.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
} else {
config.locale = Locale.TRADITIONAL_CHINESE;
eng.setTextColor(oldColor);
chi.setTextColor(getActivity().getResources().getColor(
android.R.color.white));
}
getResources().updateConfiguration(config,getResources().getDisplayMetrics());
onConfigurationChanged(config);
}
};
return changeLangListener;
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Intent intent = getActivity().getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
getActivity().finish();
startActivity(intent);
}
}
Image Share Activity:
public class SharePicForm extends Activity {
private final String TAG = "SharePicForm";
public ImageView photoArea;
public ImageView sharePhotoBtn;
public EditText shareContent;
public Bitmap mBitmap;
public Context ctx;
public String shareTxt;
//Facebook share
private Session.StatusCallback statusCallback = new SessionStatusCallback();
private PendingAction pendingAction = PendingAction.NONE;
private enum PendingAction {
NONE, POST_PHOTO
}
public static boolean isShowForm = true;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_pic_form);
ctx = this;
Utility.setHeader(this,R.string.selfie_header,false);
photoArea = (ImageView) findViewById(R.id.photo_area);
shareContent = (EditText) findViewById(R.id.share_content);
Intent intent = getIntent();
String fileUri = (String) intent.getStringExtra("photo");
FileInputStream inputStream;
try {
File imgSelected = new File(fileUri);
if (imgSelected.exists()) {
inputStream = new FileInputStream(imgSelected);
mBitmap = Utility.decodeBitmap(inputStream, 1280, 960);
photoArea.setImageBitmap(mBitmap);
sharePhotoBtn = (ImageView) findViewById(R.id.share_submit);
sharePhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mBitmap != null && FormValidation.hasText(shareContent)) {
try {
File imageToShare = saveBitmapToStorage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shareTxt = shareContent.getText().toString();
Session session = Session.getActiveSession();
if (session.isOpened()) {
Log.d(TAG,"logined");
performPublish(PendingAction.POST_PHOTO);
} else {
Log.d(TAG,"not logined");
onClickLogin();
}
//new FormSubmit(ctx).execute("shareImg",imageToShare, textToShare);
}
}
});
} else {
Utility.showDialog(ctx,"error");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private File saveBitmapToStorage () throws IOException{
String path = Environment.getExternalStorageDirectory().toString();
File outputFile = new File(path, "temp.jpg");
FileOutputStream out = new FileOutputStream(outputFile);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
return outputFile;
}
//Facebook share
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(this, true, statusCallback);
}
}
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (pendingAction != PendingAction.NONE &&
(exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)) {
new AlertDialog.Builder(ctx)
.setTitle("Cancel")
.setMessage("No grant permission")
.setPositiveButton("ok", null)
.show();
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
handlePendingAction();
}
performPublish(PendingAction.POST_PHOTO);
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null
&& session.getPermissions().contains("publish_actions");
}
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;
if (previouslyPendingAction == PendingAction.POST_PHOTO)
postPhoto();
}
private void performPublish(PendingAction action) {
Session session = Session.getActiveSession();
if (session != null) {
Log.d(TAG,"session != null");
pendingAction = action;
if (hasPublishPermission()) {
Log.d(TAG,"Has permission");
// We can do the action right away.
handlePendingAction();
return;
} else if (session.isOpened()) {
Log.d(TAG,"No permission");
// We need to get new permissions, then complete the action when we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, "publish_actions"));
return;
}
Log.d(TAG,"Session not open");
}
Log.d(TAG,"Session null");
}
private void postPhoto() {
Log.d(TAG,"postPhoto: " + hasPublishPermission());
if (hasPublishPermission()) {
if (mBitmap != null) {
Request request = Request.newUploadPhotoRequest(
Session.getActiveSession(),mBitmap, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(response.getError());
}
});
Bundle params = request.getParameters();
if (shareTxt != null)
params.putString("message", shareTxt);
request.setParameters(params);
request.executeAsync();
}
} else {
pendingAction = PendingAction.POST_PHOTO;
}
}
private void showPublishResult(FacebookRequestError error) {
if (error == null) {
Utility.showDialog(ctx,"success_photo");
} else {
Utility.showDialog(ctx,"error");
}
}
}
Thanks for helping. Any help is appreciate thanks.
Log for the share image activity
02-11 02:18:17.914: D/SharePicForm(21646): logined
02-11 02:18:17.914: D/SharePicForm(21646): session != null
02-11 02:18:17.914: D/SharePicForm(21646): No permission

You are missing the 'UiLifecycleHelper's' implementation in your Fragment:
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
//Do what ever you want to do here
}
};
onCreate(....)
{
uiHelper = new UiLifecycleHelper(VideoShareActivity.this, callback);
uiHelper.onCreate(savedInstanceState);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
Now your Session.getActiveSession() should not return null.
I hope this helps.

Related

Android Login with Facebook SDK 4.0

I hope anybody can help me ! I want to change my code for the new facebook sdk 4.0 but there is only a little description and i´m getting crazy and don´t know how to make the new code with facebook login button and accesstoken
target of this code is that the user logs in with his facebook account and checks if the user already exits. if not then insert new user with email and facebook id and name
I have marked the codes with //needs to be changed and //needs to be changed END
Thanx in advance for any help !!!
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
// import com.facebook.Request;
//import com.facebook.Request.GraphUserCallback;
// import com.facebook.Response;
// import com.facebook.Session;
// import com.facebook.SessionState;
//import com.facebook.UiLifecycleHelper;
// import com.facebook.model.GraphUser;
// import com.facebook.widget.LoginButton;
#SuppressLint("NewApi")
public class AuthenticationFragment extends Fragment {
LoginButton facebookLoginButton;
// private UiLifecycleHelper uiHelper;
String TAG = "Fragment";
Button btnLogin, btnCreateAccount;
ProgressDialog dialogPrg;
String userName = null;
// New Facebook Added
CallbackManager callbackManager;
public static final AuthenticationFragment newInstance() {
// TODO Auto-generated constructor stub
AuthenticationFragment fragment = new AuthenticationFragment();
return fragment;
}
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.authentication_layout, container,
false);
facebookLoginButton = (LoginButton) view
.findViewById(R.id.btnFacebookLogin);
facebookLoginButton.setFragment(this);
facebookLoginButton.setReadPermissions(Arrays.asList("email"));
// New added for Facebook
// Callback registration
facebookLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
//login ok get access token
AccessToken.getCurrentAccessToken();
}
#Override
public void onCancel() {
// App code
Log.i(TAG, "facebook login canceled");
}
#Override
public void onError(FacebookException exception) {
// App code
Log.i(TAG, "facebook login failed error");
}
});
//New added for Facebook END
btnLogin = (Button) view.findViewById(R.id.btn_login);
btnCreateAccount = (Button) view.findViewById(R.id.btn_create_account);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
}
});
btnCreateAccount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(getActivity(),
CreateAccountActivity.class);
startActivity(intent);
}
});
dialogPrg = new ProgressDialog(getActivity());
dialogPrg.setCanceledOnTouchOutside(false);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// uiHelper = new UiLifecycleHelper(getActivity(), callback);
// uiHelper.onCreate(savedInstanceState);
}
// Needs to be changed
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(final Session session, final SessionState state,
final Exception exception) {
onSessionStateChange(session, state, exception);
}
};
// Needs to be changed END
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (state.isOpened()) {
Log.i("FB AUT FRAGMENT", "Logged in...");
} else if (state.isClosed()) {
Log.i("FB AUT FRAGMENT", "Logged out...");
}
}
// Needs to be changed
private void insertUser(Session session) {
Request.newMeRequest(session, new GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
// TODO Auto-generated method stub
new facebookUserCheck(user).start();
}
}).executeAsync();
}
// Needs to be changed END
// Needs to be changed
private class facebookUserCheck extends Thread {
GraphUser user;
public facebookUserCheck(GraphUser user) {
// TODO Auto-generated constructor stub
this.user = user;
}
// Needs to be changed
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
// TODO Auto-generated method stub
String handleInsertUser = getActivity().getResources().getString(
R.string.users_json_url)
+ "facebook_user_check";
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(handleInsertUser);
MultipartEntity reqEntity = new MultipartEntity();
// Needs to be changed user.getId
reqEntity.addPart("fb_id", new StringBody(user.getId()));
// Needs to be changed END
post.setEntity(reqEntity);
HttpResponse res = client.execute(post);
HttpEntity resEntity = res.getEntity();
final String response_str = EntityUtils.toString(resEntity);
if (resEntity != null) {
Log.i(TAG, response_str);
getActivity().runOnUiThread(new Runnable() {
public void run() {
try {
dialogPrg.dismiss();
JSONArray jsonArray = new JSONArray(
response_str);
if (jsonArray.length() == 1) {
JSONObject obj = jsonArray.getJSONObject(0);
User user = Ultils.parseUser(obj);
UserSessionManager userSession = new UserSessionManager(
getActivity());
userSession.storeUserSession(user);
Intent intent = new Intent(getActivity(),
HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
} catch (Exception e) {
LayoutInflater inflater = LayoutInflater
.from(getActivity());
View promptsView = inflater.inflate(
R.layout.username_promtps_layout, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
getActivity());
// set prompts.xml to alertdialog builder
alertDialogBuilder.setView(promptsView);
final EditText message = (EditText) promptsView
.findViewById(R.id.editTextDialogUserInput);
alertDialogBuilder
.setMessage(getResources().getString(
R.string.choose_your_user_name));
// set dialog message
alertDialogBuilder
.setCancelable(false)
.setPositiveButton(
getResources().getString(
R.string.ok_label),
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int id) {
if (!Validator
.validUserName(message
.getText()
.toString())) {
showDialog(getResources()
.getString(
R.string.invalid_user_name));
return;
}
userName = message
.getText()
.toString();
new facebookUserRegister(
user).start();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder
.create();
// show it
alertDialog.show();
}
}
});
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
// Needs to be changed
private class facebookUserRegister extends Thread {
GraphUser user;
public facebookUserRegister(GraphUser user) {
// TODO Auto-generated constructor stub
this.user = user;
}
// Needs to be changed END
#Override
public void run() {
super.run();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
dialogPrg.show();
}
});
String handleInsertUser = getActivity().getResources().getString(
R.string.users_json_url)
+ "facebook_user_register";
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(handleInsertUser);
MultipartEntity reqEntity = new MultipartEntity();
// Needs to be changed user.getId, user.getName, user.asMap
reqEntity.addPart("fb_id", new StringBody(user.getId()));
reqEntity.addPart("fullname", new StringBody(user.getName()));
reqEntity.addPart("email", new StringBody(user.asMap().get("email").toString()));
// Needs to be changed END
reqEntity.addPart("username", new StringBody(userName));
post.setEntity(reqEntity);
HttpResponse res = client.execute(post);
HttpEntity resEntity = res.getEntity();
final String response_str = EntityUtils.toString(resEntity);
if (resEntity != null) {
Log.i(TAG, response_str);
getActivity().runOnUiThread(new Runnable() {
public void run() {
try {
dialogPrg.dismiss();
JSONObject jsonObj = new JSONObject(
response_str);
if (jsonObj.getString("ok").equals("0")) {
// show error email;
showDialog(getActivity().getResources()
.getString(R.string.email_exist));
return;
}
if (jsonObj.getString("ok").equals("1")) {
// show error username
showDialog(getActivity()
.getResources()
.getString(R.string.user_name_exist));
return;
}
if (jsonObj.getString("ok").equals("2")) {
// show unknow username
showDialog(getActivity().getResources()
.getString(R.string.login_failed));
return;
}
} catch (Exception e) {
JSONArray jsonArray;
try {
jsonArray = new JSONArray(response_str);
if (jsonArray.length() == 1) {
JSONObject obj = jsonArray
.getJSONObject(0);
User user = Ultils.parseUser(obj);
UserSessionManager userSession = new UserSessionManager(
getActivity());
userSession.storeUserSession(user);
Intent intent = new Intent(
getActivity(),
HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
showDialog(getActivity().getResources()
.getString(R.string.login_failed));
}
}
}
});
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
// Needs to be changed
#Override
public void onResume() {
super.onResume();
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed())) {
onSessionStateChange(session, session.getState(), null);
}
// uiHelper.onResume();
}
// Needs to be changed END
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// New Facebook added
callbackManager.onActivityResult(requestCode, resultCode, data);
//New Facebook added END
// uiHelper.onActivityResult(requestCode, resultCode, data);
// Needs to be changed
if (Session.getActiveSession() != null
&& Session.getActiveSession().isOpened()) {
dialogPrg.setMessage(getActivity().getResources().getString(
R.string.loging));
dialogPrg.show();
facebookLoginButton.setEnabled(false);
insertUser(Session.getActiveSession());
}
}
// Needs to be changed END
#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);
}
public void showDialog(String message) {
Ultils.logout(getActivity());
AlertDialog.Builder buidler = new AlertDialog.Builder(getActivity());
buidler.setMessage(message);
buidler.setPositiveButton(
getActivity().getResources().getString(R.string.ok_label),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method
// stub
facebookLoginButton.setEnabled(true);
}
});
AlertDialog dialog = buidler.create();
dialog.show();
}
}
Use this Snippet for facebook login. Works like a charm in my app.
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import com.facebook.AppEventsLogger;
import com.facebook.FacebookAuthorizationException;
import com.facebook.FacebookOperationCanceledException;
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.FacebookDialog;
import com.facebook.widget.LoginButton;
import com.facebook.widget.ProfilePictureView;
import com.ids.service.R;
import android.support.v4.app.FragmentActivity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends FragmentActivity {
private final String PENDING_ACTION_BUNDLE_KEY = "com.facebook.samples.hellofacebook:PendingAction";
private LoginButton loginButton;
private ProfilePictureView profilePictureView;
private PendingAction pendingAction = PendingAction.NONE;
private GraphUser user;
private GraphPlace place;
private List<GraphUser> tags;
private boolean canPresentShareDialog;
private boolean canPresentShareDialogWithPhotos;
private enum PendingAction {
NONE,
POST_PHOTO,
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("Facebook", String.format("Error: %s", error.toString()));
}
#Override
public void onComplete(FacebookDialog.PendingCall pendingCall, Bundle data) {
Log.d("Facebook", "Success!");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String name = savedInstanceState.getString(PENDING_ACTION_BUNDLE_KEY);
pendingAction = PendingAction.valueOf(name);
}
setContentView(R.layout.activity_main);
profilePictureView = (ProfilePictureView) findViewById(R.id.profilePicture);
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();
}
});
}
#Override
protected void onResume() {
super.onResume();
uiHelper.onResume();
// Call the 'activateApp' method to log an app event for use in analytics and advertising reporting. Do so in
// the onResume methods of the primary Activities that an app may be launched into.
AppEventsLogger.activateApp(this);
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();
// Call the 'deactivateApp' method to log an app event for use in analytics and advertising
// reporting. Do so in the onPause methods of the primary Activities that an app may be launched into.
AppEventsLogger.deactivateApp(this);
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (pendingAction != PendingAction.NONE &&
(exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)) {
new AlertDialog.Builder(MainActivity.this)
.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();
}
#SuppressWarnings("unused")
private void updateUI() {
Session session = Session.getActiveSession();
if (user != null) {
profilePictureView.setProfileId(user.getId());
Log.e("Name", user.getName());
}
}
#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_PHOTO:
postPhoto();
break;
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();
}
private FacebookDialog.ShareDialogBuilder createShareDialogBuilderForLink() {
return new FacebookDialog.ShareDialogBuilder(this)
.setName("Hello Facebook")
.setDescription("The 'Hello Facebook' sample application showcases simple Facebook integration")
.setLink("http://developers.facebook.com/android");
}
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;
}
}
private FacebookDialog.PhotoShareDialogBuilder createShareDialogBuilderForPhoto(Bitmap... photos) {
return new FacebookDialog.PhotoShareDialogBuilder(this)
.addPhotos(Arrays.asList(photos));
}
private void postPhoto() {
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher);
if (canPresentShareDialogWithPhotos) {
FacebookDialog shareDialog = createShareDialogBuilderForPhoto(image).build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else if (hasPublishPermission()) {
Request request = Request.newUploadPhotoRequest(Session.getActiveSession(), image, new Request.Callback() {
#Override
public void onCompleted(Response response) {
showPublishResult(getString(R.string.photo_post), response.getGraphObject(), response.getError());
}
});
request.executeAsync();
} else {
pendingAction = PendingAction.POST_PHOTO;
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains("publish_actions");
}
}
As you can read in the Facebook SDK for Android changelog in section 4.0 - March 25, 2015 the UiLifecycleHelper was removed and its functionality transferred to the CallbackManager.
Here is a tutorial which explains how to implement the login with facebook SDK 4.0.

Why the facebook sdk in android missed the permission?

I am using the latest facebook sdk , I tried to follow the offical sample to create a own login button , however, I found a strange behavior in my app.
After I logined, a permission dialog is pop up, even though I clicked on accept , it is still fall into the authorization exception and show permission not found, how to fix it ?
Thanks
public class SharePicForm extends Activity implements LoginListener,
UploadImageListener {
private final String TAG = "SharePicForm";
public ImageView photoArea;
public ImageView sharePhotoBtn;
public TextView shareTitle;
public EditText shareContent;
public Bitmap mBitmap;
public Context ctx;
public String shareTxt;
public String fileUri;
public static boolean isShowForm = true;
public EasyTracker tracker = null;
public SharedPreferences prefs;
public String catId;
public File savedBitmap;
public Editor editor;
public ProgressDialog pd;
// Facebook share
private PendingAction pendingAction = PendingAction.NONE;
private enum PendingAction {
NONE, POST_PHOTO
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_pic_form);
ctx = this;
prefs = ctx.getSharedPreferences("userInfo", 0);
editor = prefs.edit();
tracker = EasyTracker.getInstance(this);
Utility.setHeader(this, "selfie", false);
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(this, null, callback,
savedInstanceState);
}
if (session == null) {
session = new Session(this);
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("basic_info","email")).setCallback(callback));
}
}
photoArea = (ImageView) findViewById(R.id.photo_area);
int size = (int) (Utility.getScreenWidth(this) - 220);
RelativeLayout.LayoutParams imgParams = new RelativeLayout.LayoutParams(size, size);
imgParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
imgParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
// imgParams.addRule(RelativeLayout.ABOVE, R.id.share_title);
photoArea.setAdjustViewBounds(true);
photoArea.setLayoutParams(imgParams);
photoArea.setBackgroundResource(android.R.color.darker_gray);
photoArea.getBackground().setAlpha(204); // = 0.8 alpha
shareTitle = (TextView) findViewById(R.id.share_title);
shareContent = (EditText) findViewById(R.id.share_content);
shareContent.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.share_content) {
v.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
}
return false;
}
});
if (getIntent() != null) {
Intent intent = getIntent();
fileUri = (String) intent.getStringExtra("photo");
catId = (String) intent.getStringExtra("catId");
} else if (savedInstanceState != null) {
mBitmap = (Bitmap) savedInstanceState.getParcelable("bitmap") == null ? null
: (Bitmap) savedInstanceState.getParcelable("bitmap");
catId = (String) savedInstanceState.getString("catId");
}
savedBitmap = new File(fileUri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap beforeScale = BitmapFactory.decodeFile(fileUri, options);
if (beforeScale.getWidth() > 1280) {
mBitmap = ThumbnailUtils.extractThumbnail(beforeScale, 1280, 1280);
FileOutputStream fos;
try {
fos = new FileOutputStream(savedBitmap);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
mBitmap = beforeScale;
}
if (mBitmap == null) {
Toast.makeText(ctx,ctx.getResources().getString(R.string.get_photo_error),Toast.LENGTH_SHORT).show();
finish();
} else {
photoArea.setImageBitmap(mBitmap);
sharePhotoBtn = (ImageView) findViewById(R.id.share_submit);
sharePhotoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
tracker.send(MapBuilder.createEvent("form_button",
"Category_form",
"SubmitnShare_" + Utility.getLocale(ctx), null)
.build());
performPublish(PendingAction.POST_PHOTO);
}
});
}
}
// Facebook share
#SuppressWarnings("deprecation")
private void onSessionStateChange(final Session session,
SessionState state, Exception exception) {
Log.d(TAG, "" + exception);
if (pendingAction != PendingAction.NONE && exception != null) {
if (!session.isClosed())
session.closeAndClearTokenInformation(); // reset session
if (exception instanceof FacebookAuthorizationException) {
new AlertDialog.Builder(SharePicForm.this)
.setTitle(ctx.getResources().getString(R.string.error))
.setMessage(
ctx.getResources().getString(
R.string.facebook_permission_missing))
.setPositiveButton(
ctx.getResources().getString(R.string.close),
null).show();
}
pendingAction = PendingAction.NONE;
} else if (state == SessionState.OPENED_TOKEN_UPDATED) {
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,
Response response) {
// TODO Auto-generated method stub
if (user != null) {
if (!user.getId().equals(
prefs.getString("fbId", ""))) {
editor.putString("fbId", user.getId());
editor.putString("fName",
user.getFirstName());
editor.putString("lName",
user.getLastName());
if (user.getProperty("email") != null) {
editor.putString("email", user.getProperty("email").toString());
}
editor.commit();
}
if (prefs.getString("memId", "").equals("")
|| prefs.getString("token", "").equals(
"")
|| !user.getId().equals(
prefs.getString("fbId", ""))) {
pd = ProgressDialog.show(
ctx,
getResources().getString(
R.string.sys_info),
getResources().getString(
R.string.loading));
new APIHandler(ctx, tracker, "login", pd)
.execute(ctx,
session.getAccessToken());
} else {
onLoginComplete("", "");
}
}
}
});
} else if (session != null && session.isOpened()) {
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(
this, "publish_actions")); // login complete
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null
&& session.getPermissions().contains("publish_actions");
}
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;
if (previouslyPendingAction == PendingAction.POST_PHOTO) {
MyApp appState = ((MyApp) getApplicationContext());
boolean isGameClose = appState.getState();
if (isGameClose) {
Toast.makeText(this,
getResources().getString(R.string.game_close),
Toast.LENGTH_LONG).show();
} else {
pd = ProgressDialog.show(ctx,
getResources().getString(R.string.sys_info),
getResources().getString(R.string.publishing));
postPhoto();
}
}
}
private void performPublish(PendingAction action) {
Log.d(TAG, "Perform publish");
Session session = Session.getActiveSession();
if (session != null) {
Log.d(TAG, "Session != null");
pendingAction = action;
if (hasPublishPermission()) {
Log.d(TAG, "Has permission");
// We can do the action right away.
handlePendingAction();
return;
} else if (session.isOpened()) {
Log.d(TAG, "Open session");
// We need to get new permissions, then complete the action when
// we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, "publish_actions"));
return;
} else {
onClickLogin();
}
} else {
Log.d(TAG, "Session == null");
}
}
private void onClickLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("basic_info","email")).setCallback(callback));
} else {
Session.openActiveSession(this, true, callback);
}
}
private void postPhoto() {
Log.d(TAG, "postPhoto: " + hasPublishPermission());
if (hasPublishPermission()) {
Request request = Request.newUploadPhotoRequest(
Session.getActiveSession(), mBitmap,
new Request.Callback() {
#Override
public void onCompleted(Response response) {
if (response.getError() == null
&& savedBitmap != null) {
new APIHandler(ctx, tracker, "uploadImg", pd)
.execute(ctx, shareTxt, savedBitmap,
catId);
} else {
if (pd != null)
pd.dismiss();
Log.d(TAG, response.getError()
.getErrorMessage());
Toast.makeText(ctx,
response.getError().getErrorMessage(),
Toast.LENGTH_LONG).show();
Utility.showDialog(ctx, "error", tracker);
}
}
});
Bundle params = request.getParameters();
shareTxt = shareContent.getText().toString().equals("") ? getResources().getString(R.string.default_msg) : shareContent.getText().toString();
params.putString("message", shareTxt);
request.setParameters(params);
request.executeAsync();
} else {
if (pd != null)
pd.dismiss();
pendingAction = PendingAction.POST_PHOTO;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mBitmap != null) {
outState.putParcelable("bitmap", mBitmap);
}
if (catId != null) {
outState.putString("catId", catId);
}
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
#Override
public void onStart() {
super.onStart();
Session.getActiveSession().addCallback(callback);
EasyTracker.getInstance(this).activityStart(this);
tracker.set(Fields.SCREEN_NAME, "hk7app/CX/" + Utility.getLocale(this)
+ "/Image_entryForm");
tracker.send(MapBuilder.createAppView().build());
}
#Override
public void onStop() {
if (pd != null)
pd.dismiss();
super.onStop();
Session.getActiveSession().removeCallback(callback);
EasyTracker.getInstance(this).activityStop(this);
}
#Override
public void onDestroy() {
if (savedBitmap != null && savedBitmap.exists())
savedBitmap.delete();
super.onDestroy();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode,
resultCode, data);
}
#Override
public void onResume() {
super.onResume();
AppEventsLogger.activateApp(this,
getResources().getString(R.string.app_id));
}
#Override
public void onLoginComplete(String memberId, String token) {
if (pd != null)
pd.dismiss();
if (!memberId.equals("") && !token.equals("")) {
editor.putString("memId", memberId);
editor.putString("token", token);
editor.commit();
}
handlePendingAction();
}
#Override
public void onLoginFailure(String errorMsg) {
if (pd != null)
pd.dismiss();
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
}
#Override
public void onImageUploadComplete(int isFormCompleted) {
if (pd != null)
pd.dismiss();
if (isFormCompleted == 1) {
Utility.showDialog(ctx, "success", tracker);
} else {
Intent intent = new Intent(ctx, PersonalInfoForm.class);
ctx.startActivity(intent);
finish();
}
}
#Override
public void onImageUploadFailure(String errorMsg) {
if (pd != null)
pd.dismiss();
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
}
}
My suggestion would be to use separate Session.StatusCallback implementations for 'login' and 'requestPostPermission'.
private Session.StatusCallback callbackLogin = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.removeCallback( this );
if ( session.isOpen() ) {
...
} else if ( session.isClosed() ) {
...
}
}
};
and for postPermissions:
private Session.StatusCallback callbackPostPermission = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state,
Exception exception) {
session.removeCallback( this );
if ( session.isOpen() ) {
if ( session.getPermissions().contains( "publish_actions" ) {
...
} else {
...
}
...
} else if ( session.isClosed() ) {
...
}
}
};

Facebook login shows error message in Android

I am working on Facebook integration on my Android app. It's working fine on some device, but on some device it's not working and give me error message:
Below is the code :
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 void onSessionStateChange(Session session, SessionState state, Exception exception) {
if ( exception instanceof FacebookOperationCanceledException ||
exception instanceof FacebookAuthorizationException)
{
new AlertDialog.Builder(MainWindow.this)
.setTitle("cancel")
.setMessage("your permission has expired.")
.setPositiveButton("ok", null)
.show();
}
}
private void onClickFacebookRequest()
{
if (session.isOpened())
{
sendRequests();
} else {
StatusCallback callback = new StatusCallback() {
public void call(Session session, SessionState state, Exception exception) {
if (exception != null) {
new AlertDialog.Builder(MainWindow.this)
.setTitle(R.string.login_failed_dialog_title)
.setMessage(exception.getMessage())
.setPositiveButton(R.string.ok_button, null)
.show();
session = createSession();
}
}
};
pendingRequest = true;
session.openForRead(new Session.OpenRequest(this).setCallback(callback));
}
}
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
private void sendRequests()
{
List<String> permissions = quytechApps.getSession().getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingRequest = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
showValidationDialog("Please Wait.posting Data on Facebook");
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.splash_screen_final4);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bundle postParams=new Bundle();
postParams.putByteArray("photo",byteArray);
postParams.putString("message", "Hi Friends I am using Twinqli Chat App.");
Request request = new Request(Session.getActiveSession(), "me/photos", postParams, HttpMethod.POST, new Request.Callback()
{
#Override
public void onCompleted(Response response) {
// TODO Auto-generated method stub
// showPublishResult(getString(R.string.photo_post), response.getGraphObject(), response.getError());
if(response.getError() == null)
{
Log.d("GraphApiSample.java Sucesses","sucess");
dismissValidatingDialog();
}
else
{
dismissValidatingDialog();
session.closeAndClearTokenInformation();
//quytechApps.getSession().
//quytechApps.setSession(null);
// Log.d("GraphApiSample.java",""+response.getError().getErrorMessage());
}
}
});
request.executeAsync();
}
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
static final String applicationId = "390611174384274";
boolean pendingRequest;
static final String PENDING_REQUEST_BUNDLE_KEY = "com.facebook.samples.graphapi:PendingRequest";
private Session createSession()
{
Session activeSession = Session.getActiveSession();
if (activeSession == null || activeSession.getState().isClosed())
{
activeSession = new Session.Builder(this).setApplicationId(applicationId).build();
Session.setActiveSession(activeSession);
}
return activeSession;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (qsession.onActivityResult(this, requestCode, resultCode, data) &&
pendingRequest &&
session.getState().isOpened()) {
sendRequests();
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
pendingRequest = savedInstanceState.getBoolean(PENDING_REQUEST_BUNDLE_KEY, pendingRequest);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(PENDING_REQUEST_BUNDLE_KEY, pendingRequest);
}
Can anyone tell me what's wrong in my code?
This problem normally occurs when the facebook app in your phone is not updated so please update it and then check.
It worked for me hope it will work for you also.
EDIT:
To check the hash key put this in your onCreate Method
PackageInfo info;
try {
info = getPackageManager().getPackageInfo("com.example.yourpackagename", PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md;
md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
String something = new String(Base64.encode(md.digest(), 0));
//String something = new String(Base64.encodeBytes(md.digest()));
Log.e("hash key", something);
}
} catch (NameNotFoundException e1) {
Log.e("name not found", e1.toString());
} catch (NoSuchAlgorithmException e) {
Log.e("no such an algorithm", e.toString());
} catch (Exception e) {
Log.e("exception", e.toString());
}

Keep getting an UnsupportedOperationException when requesting a new permission

I am new to the facebook sdk, so I am not really too sure why I am getting this error. I have narrowed it down to this section:
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
Here>> session.requestNewPublishPermissions(newPermissionsRequest); <<Here
return;
} //this code is located below in the publishStory() method
I followed both the Authenticate tutorial, and the Publish Feed tutorial exactly as is, with a bit of reordering to suit my needs. I am not sure what I could have possibly missed. I will post the SelectionFragment class, which I put the post status stuff to because its where a user is logged in. Just to make sure this is clear, logging in works perfectly. But when I try to click post status it does nothing. The second time I click it, it crashes. Any explanation would be most appreciated.
public class SelectionFragment extends Fragment{
private static final int REAUTH_ACTIVITY_CODE = 100;
private ProfilePictureView profilePictureView;
private TextView userNameView;
private UiLifecycleHelper uiHelper;
private Button shareButton;
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private static final String PENDING_PUBLISH_KEY = "pendingPublishReauthorization";
protected static final String TAG = "SelectionFragment.java";
private boolean pendingPublishReauthorization = false;
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(final Session session, final SessionState state, final Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}//end of onCreate()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.selection, container, false);
// Find the user's profile picture custom view
profilePictureView = (ProfilePictureView) view.findViewById(R.id.selection_profile_pic);
profilePictureView.setCropped(true);
// Find the user's name view
userNameView = (TextView) view.findViewById(R.id.selection_user_name);
//find the share button
shareButton = (Button) view.findViewById(R.id.shareButton);
shareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
publishStory();
}
});
// Check for an open session
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// Get the user's data
makeMeRequest(session);
}
if (savedInstanceState != null) {
pendingPublishReauthorization =
savedInstanceState.getBoolean(PENDING_PUBLISH_KEY, false);
}
return view;
}//end of onCreateView
/*
* Private method that requests users data
* */
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 == Session.getActiveSession()) {
if (user != null) {
// 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();
}
/*
* private method that will respond to session changes and call
* the makeMeRequest() method if the session's open
* */
private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
if (session != null && session.isOpened()) {
// Get the user's data.
makeMeRequest(session);
}
/*The following checks if user is logged in and hides or shows the share button*/
if (state.isOpened()) {
shareButton.setVisibility(View.VISIBLE);
if (pendingPublishReauthorization &&
state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
pendingPublishReauthorization = false;
publishStory();
}
} else if (state.isClosed()) {
shareButton.setVisibility(View.INVISIBLE);
}
}//end of onSessionStateChanged
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REAUTH_ACTIVITY_CODE) {
uiHelper.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
bundle.putBoolean(PENDING_PUBLISH_KEY, pendingPublishReauthorization);
uiHelper.onSaveInstanceState(bundle);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
/*
* What actually publishes the status update
* */
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook SDK for Android");
postParams.putString("caption", "Build great social apps and get more installs.");
postParams.putString("description", "The Facebook SDK for Android makes it easier and faster to develop Facebook integrated Android apps.");
postParams.putString("link", "https://developers.facebook.com/android");
postParams.putString("picture", "https://raw.github.com/fbsamples/ios-3.x-howtos/master/Images/iossdk_logo.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response
.getGraphObject()
.getInnerJSONObject();
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i(TAG,
"JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity()
.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity()
.getApplicationContext(),
postId,
Toast.LENGTH_LONG).show();
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}//end of publishStory
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
}//end of class
Edit
Ok so I was able to finally post, but now I have figured out why its crashing still. The last method in the above class, isSubset seems to always return false, meaning it will always run, even if the publish permission was already created.
Edit 2
public class FacebookFrag extends FragmentActivity {
private static final int SPLASH = 0;
private static final int SELECTION = 1;
private static final int SETTINGS = 2;
private static final int FRAGMENT_COUNT = SETTINGS +1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT];
private MenuItem settings;
//flag that indicates a visible activity
private boolean isResumed = false;
private UiLifecycleHelper uiHelper;
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);
setContentView(R.layout.facebook_layout);
FragmentManager fm = getSupportFragmentManager();
fragments[SPLASH] = fm.findFragmentById(R.id.splashFragment);
fragments[SELECTION] = fm.findFragmentById(R.id.selectionFragment);
fragments[SETTINGS] = fm.findFragmentById(R.id.userSettingsFragment);
FragmentTransaction transaction = fm.beginTransaction();
for(int i = 0; i < fragments.length; i++) {
transaction.hide(fragments[i]);
}
transaction.commit();
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
}
private void showFragment(int fragmentIndex, boolean addToBackStack) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
for (int i = 0; i < fragments.length; i++) {
if (i == fragmentIndex) {
transaction.show(fragments[i]);
} else {
transaction.hide(fragments[i]);
}
}
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
// Only make changes if the activity is visible
if (isResumed) {
FragmentManager manager = getSupportFragmentManager();
// Get the number of entries in the back stack
int backStackSize = manager.getBackStackEntryCount();
// Clear the back stack
for (int i = 0; i < backStackSize; i++) {
manager.popBackStack();
}
if (state.isOpened()) {
// If the session state is open:
// Show the authenticated fragment
showFragment(SELECTION, false);
} else if (state.isClosed()) {
// If the session state is closed:
// Show the login fragment
showFragment(SPLASH, false);
}
}
}
#Override
protected void onResumeFragments() {
super.onResumeFragments();
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// if the session is already open,
// try to show the selection fragment
showFragment(SELECTION, false);
} else {
// otherwise present the splash screen
// and ask the person to login.
showFragment(SPLASH, false);
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// only add the menu when the selection fragment is showing
if (fragments[SELECTION].isVisible()) {
if (menu.size() == 0) {
settings = menu.add(R.string.settings);
}
return true;
} else {
menu.clear();
settings = null;
}
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.equals(settings)) {
showFragment(SETTINGS, true);
return true;
}
return false;
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
isResumed = true;
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
isResumed = false;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
}//end of class
just remove the return from your publishstory();And make sure that your session is in OPEN state when you call publishstory().
//
if(isNetworkAvailable()){
/* ~post your data only if session is in OPEN state also check
for login and internet connection*/
Session session=Session.getActiveSession();
if(session!=null){
MyLog.w("session state",session.getState().toString());
if(session.getState()==SessionState.OPENED){
publishStory();
}else{
showAlertDialog("Unable to Share");
}
}else{
showAlertDialog("Please login first!");
}
}else{
showAlertDialog("Problem occured with your internet connection");
}
remove return statement
if (!isSubsetOf(PERMISSIONS, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS);
session.requestNewPublishPermissions(newPermissionsRequest);
`Remove this===>` return;
}
Normally, when you got UnsupportedOperationException, it means that the device cannot find the method that used in your app.
Something you need to check:
The Android version of emulator or test device must be greater than the Min SDK?
All the library is included and exported correctly?

Why does facebook login work during development, but not during deployment?

when I install my app via ADB via Eclipse, then the facebook logon as well as publishing to the wall of the user works (using facebook SDK 3.0), but when I package my app and then install that app, then the facebook logon does not work. I get the fragment with a logon button, when I push the logon button, then it shows the dialog that the app wants to have access to my public profile and friendlist. When I click ok it goes back to the fragment with the login button.
My question is: What should I change to make the facebook SDK integration work during deployment time as well?
my code of the fragment (erased non-relevant parts):
public class Fragment_shareFacebook extends SherlockFragment {
Context context; //context and fields:
View v;
private Button shareButton;
private MainActvityCommunicatorIntentBasedLeaveManagement intentleaveset;
private EditText toshareText;
private TextView textInstructionsOrLink, sharedText, fb_share_title_preview, fb_share_text_preview, sharesubsubtitle;
private ViewSwitcher switcher;
private LinearLayout fb_preview_keeper, mainlayoutholderfbshare, loggedinscreen;
String subject, content;
private boolean switched;
private UiLifecycleHelper uiHelper;
private static final int REAUTH_ACTIVITY_CODE = 100;
private UserSettingsFragment usersetting;
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions");
private Session.StatusCallback callback =
new Session.StatusCallback() {
#Override
public void call(Session session,
SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
/**
* empty constructor
*/
public Fragment_shareFacebook(){
}
#Override
/**
* initialize the intentleaveset to inform main that we have an intent based leave standing by
*/
public void onAttach(Activity activity) {
super.onAttach(activity);
context = getActivity();
intentleaveset=(MainActvityCommunicatorIntentBasedLeaveManagement) context;
}
#Override
/**
* get the content that needs to be shared, also retrieve the pendingPublishReauthorization if necessary
*/
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setHasOptionsMenu(true);
uiHelper = new UiLifecycleHelper(this.getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
subject = getArguments().getString("subject");
content = getArguments().getString("text");
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
Session session = Session.getActiveSession();
this.onSessionStateChange(session, session.getState(), null);
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==REAUTH_ACTIVITY_CODE){
uiHelper.onActivityResult(requestCode, resultCode, data);
}
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onDestroyView(){
//note: we have to remove the fragment again!
try{
FragmentTransaction transaction = this.getActivity().getSupportFragmentManager().beginTransaction();
transaction.remove(usersetting);
transaction.commit();
}catch(Exception e){
}
super.onDestroyView();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
//hvg: dze even disecten.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_facebook_share, container, false);
textInstructionsOrLink = (TextView) v.findViewById(R.id.textInstructionsOrLink);
fb_share_title_preview= (TextView) v.findViewById(R.id.fbsharetitlepreview);
fb_share_text_preview= (TextView) v.findViewById(R.id.fbsharetextpreview);
sharesubsubtitle=(TextView) v.findViewById(R.id.sharesubsubtitle);
loggedinscreen=(LinearLayout) v.findViewById(R.id.loggedinscreen);
usersetting=(UserSettingsFragment) this.getActivity().getSupportFragmentManager().findFragmentById(R.id.userSettingsFragment);
//authButton = (LoginButton) v.findViewById(R.id.authButton);
shareButton = (Button) v.findViewById(R.id.shareButton);
//usernamefield= (TextView) v.findViewById(R.id.selection_user_name);
toshareText = (EditText) v.findViewById(R.id.toshareText);
fb_preview_keeper= (LinearLayout) v.findViewById(R.id.fb_preview_keeper);
mainlayoutholderfbshare = (LinearLayout) v.findViewById(R.id.mainlayoutholderfbshare);
switcher=(ViewSwitcher)v.findViewById(R.id.fb_switcher);
mainlayoutholderfbshare.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(toshareText.isFocused()){
Log.i("Focussed", "--" + event.getX() + " : " + event.getY() + "--");
if (toshareText.isFocused()) {
Rect outRect = new Rect();
toshareText.getGlobalVisibleRect(outRect);
if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
toshareText.clearFocus();
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
Log.i("X-Y coordinate", "--" + event.getX() + " : " + event.getY() + "--");
//Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show();
return false;
}
});
//toshareText.setText(content);
switcher=(ViewSwitcher) v.findViewById(R.id.fb_switcher);
sharedText=(TextView) v.findViewById(R.id.sharedText);
if(switcher.getDisplayedChild()==0){
switched=false;
}else{
switched=true;
}
//note that we need a custom onclicklistener to share the story to fb
shareButton.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
intentleaveset.setIntentleave(true);
publishStory();
}
});
//note to main: we are leaving with an intent!
intentleaveset.setIntentleave(true);
Log.d("fsf: leaveintent","settrue");
Session session = Session.getActiveSession();
SessionState state = Session.getActiveSession().getState();
onSessionStateChange(session, state, null);
return v;
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
// Only make changes if the activity is visible
intentleaveset.setIntentleave(true);
Log.d("switcher-init", Integer.toString(switcher.getDisplayedChild()));
if (state.isOpened()) {
// If the session state is open:
// Show the authenticated fragment
shareButton.setVisibility(View.VISIBLE);
toshareText.setVisibility(View.VISIBLE);
fb_preview_keeper.setVisibility(View.VISIBLE);
LayoutParams params = fb_preview_keeper.getLayoutParams();
params.height=LayoutParams.WRAP_CONTENT;
params.width=LayoutParams.MATCH_PARENT;
fb_preview_keeper.setLayoutParams(params);
params=shareButton.getLayoutParams();
params.height=LayoutParams.WRAP_CONTENT;
params.width=LayoutParams.MATCH_PARENT;
shareButton.setLayoutParams(params);
params=toshareText.getLayoutParams();
params.width=LayoutParams.MATCH_PARENT;
params.height=LayoutParams.WRAP_CONTENT;
toshareText.setLayoutParams(params);
toshareText.setMinLines(3);
toshareText.setScroller(new Scroller(context));
toshareText.setVerticalScrollBarEnabled(true);
fb_share_title_preview.setText(subject);
fb_share_text_preview.setText(getString(R.string.facebook_share_subtitle).concat("\n \n").concat(content));
if(!switched){
textInstructionsOrLink.setText(getString(R.string.facebookexplanationafterlgoong));
}else{
textInstructionsOrLink.setText(getString(R.string.facebookexplanationaftershared));
if(switcher.getDisplayedChild()!=1){
switcher.showNext();
}
/*
if(switcher.getDisplayedChild()==1){
switcher.showPrevious();
}else{
switcher.showNext();
}
*/
}
params=loggedinscreen.getLayoutParams();
params.height=LayoutParams.WRAP_CONTENT;
loggedinscreen.setLayoutParams(params);
sharesubsubtitle.setFocusable(true);
sharesubsubtitle.requestFocus();
} else {
// If the session state is closed:
// Show the login fragment
if(switcher.getDisplayedChild()==1){
switcher.showPrevious();
}
switched=false;
shareButton.setVisibility(View.INVISIBLE);
//shareButton.setHeight(0);
toshareText.setVisibility(View.INVISIBLE);
//toshareText.setHeight(0);
//LayoutParams params = switcher.getLayoutParams();
//params.height=0;
//params.width=params.MATCH_PARENT;
//switcher.setLayoutParams(params);
//fb_preview_keeper.setVisibility(View.INVISIBLE);
//params = fb_preview_keeper.getLayoutParams();
//params.height=0;
//params.width=params.MATCH_PARENT;
//fb_preview_keeper.setLayoutParams(params);
LayoutParams params=loggedinscreen.getLayoutParams();
params.height=0;
loggedinscreen.setLayoutParams(params);
sharedText.setText("");
textInstructionsOrLink.setText(this.getResources().getString(R.string.facebookexplainbeforelogon));
}
}
private void publishStory() {
Session session = Session.getActiveSession();
if (session != null){
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, PERMISSIONS)
.setRequestCode(REAUTH_ACTIVITY_CODE);
session.requestNewPublishPermissions(newPermissionsRequest);
//session.reauthorizeForPublish(newPermissionsRequest);
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", subject);
postParams.putString("caption", getString(R.string.facebook_share_subtitle));
postParams.putString("description", content);
if(toshareText.getText()!=null){
postParams.putString("message", toshareText.getText().toString());
}else{
postParams.putString("message", " ");
}
postParams.putString("link", "http://www.thewonderweeks.com");
postParams.putString("picture", "www.thewonderweeks.com/apple-touch-icon-114x114.png");
Request.Callback callback= new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse;
try{
graphResponse = response
.getGraphObject()
.getInnerJSONObject();
}catch (Exception e){
if(e.getMessage()!=null){
Log.d("errorinFBcallback", e.getMessage());
}
return ;
}
String postId = null;
try {
postId = graphResponse.getString("id");
} catch (JSONException e) {
Log.i("errormessagefacebookfragmenthtingy",
"JSON error "+ e.getMessage());
}
FacebookRequestError error = response.getError();
if (error != null) {
Toast.makeText(getActivity()
.getApplicationContext(),
error.getErrorMessage(),
Toast.LENGTH_SHORT).show();
} else {
Log.d("post id of posted material", postId);
shareButton.setVisibility(View.INVISIBLE);
if(switcher.getDisplayedChild()!=1){
switcher.showNext();
}
switched=true;
sharedText.setText(getString(R.string.successhare).concat(" ").concat(toshareText.getText().toString()));
textInstructionsOrLink.setText(getString(R.string.facebookexplanationaftershared));
}
}
};
Request request = new Request(session, "me/feed", postParams,
HttpMethod.POST, callback);
RequestAsyncTask task = new RequestAsyncTask(request);
task.execute();
}
}
I assume you followed the facebook developers tutorial. If so, you use this command to produce your key
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
You must also create a key with release keystore and register it to facebook.

Categories

Resources