Facebook session state OPENING - android

I can login to my app then share something. This needs an OPENED session state. However, when I am not logged in, then I want to share something, I need to open the session. I am using a ViewPager so e.g. when I go from one page to another and this code
Session.openActiveSession(getActivity(), true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
});
is in the beginning of the code, then the session becomes active, and I get automatically logged in, which is wrong! That's why I put this code block into an onClickListener, so I only want to open the session if I click the share button in my app:
if (session != null && session.isOpened()) {
publishFeedDialog();
}
else {
Session.openActiveSession(getActivity(), true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
});
publishFeedDialog();
}
private void publishFeedDialog() {
session = Session.getActiveSession();
Log.i("TAG", session.getState() + ""); //OPENING
WebDialog feedDialog = (
new WebDialog.FeedDialogBuilder(getActivity(),
Session.getActiveSession(),
params))
.setOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(Bundle values,
FacebookException error) {
if (error == null) {
final String postId = values.getString("post_id");
if (postId != null) {
} else {
// User clicked the Cancel button
}
} else if (error instanceof FacebookOperationCanceledException) {
} else {
// Generic, ex: network error
}
}
})
.build();
feedDialog.show();
}
The error:
Attempted to use a session that was not open.
So I open the session in vain, because it is still OPENING when the WebDialog should appear.
Please help.

For me it works like this:
if (Session.getActiveSession() != null && Session.getActiveSession().isOpened()) {
publishFeedDialog();
}
else {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
// List<String> permissions = new ArrayList<String>();
// permissions.add("email");
session.openForRead(new Session.OpenRequest(this)
// .setPermissions(permissions)
.setCallback(mFacebookCallback));
} else {
Session.openActiveSession(getActivity(), true, mFacebookCallback);
}
}`
where callback is
private Session.StatusCallback mFacebookCallback = new Session.StatusCallback() {
#Override
public void
call(final Session session, final SessionState state, final Exception exception) {
if (state.isOpened()) {
String facebookToken = session.getAccessToken();
Log.i("MainActivityFaceBook", facebookToken);
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user,
com.facebook.Response response) {
publishFeedDialog();
}
}).executeAsync();
Prefs.setStringProperty(getActivity(), R.string.key_prefs_facebook_token, facebookToken);
}
}
};
Try to call publishFeedDialog() in CallBack onCompleted

Try calling publishFeedDialog() from inside call() after you check for the status of the session (do not use session.isOpened(), use state.isOpened() instead). Checking the state ensures that your Session is in an open state and that it can also be used to execute requests. The StatusCallback can be called multiple times until the Session is actually open, that is why you should check the status before sending any request.

If you are opening a session from a fragment use the next openActiveSession method implementation.
openActiveSession(Context context, Fragment fragment, boolean allowLoginUI, Session.StatusCallback callback)
This works for me.

Related

Getting email from GraphUser with Permissions

I'm attempting a log-in with FB with the code below. The GraphUser object has first name, last name, ID, but not email. I know I need to add permissions but how do I do it in this case. The permissions are generally added with Session.OpenRequest or the LogInButton but I'm not using those. Any suggestions?
Session.openActiveSession(activity, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
// get email from GraphUser
}
}
}).executeAsync();
}
}
});
I you have more than one permissions then make a list of permissions and call the performPublish() method (where you will be passing that Permission list as parameter) to publish a permission and with that check for the publish permission.
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions", "email");
private void performPublish() {
Session session = Session.getActiveSession();
if (session != null) {
if (hasPublishPermission()) {
postStatusUpdate("name");
} else {
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, PERMISSIONS));
}
}
}
private boolean hasPublishPermission() {
Session session = Session.getActiveSession();
return session != null && session.getPermissions().contains("publish_actions");
}
Just add the permissions as a parameter in openActiveSession:
Session.openActiveSession(activity, true, Arrays.asList("public_profile", "email"), new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
// get email from GraphUser
}
}
}).executeAsync();
}
}
});

How to add permission for getting birthday from Facebook

I'm unable to add permission for birthday, please help me out...
thanks in advance.
sample source code is :
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#SuppressWarnings("deprecation")
#Override
public void call(Session session, SessionState state,
Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
// callback after Graph API response with user
// object
#Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
}
}
});
}
}
});
Try this,
.setPermissions(Arrays.asList("user_birthday","email"))
private static final List PERMISSIONS = Arrays.asList(""user_birthday""); //declaration
onClickPostStatusUpdate();// on button click call this function
private void onClickPostStatusUpdate() {
performPublish(PendingAction.POST_STATUS_UPDATE);
}
private void performPublish(PendingAction action) {
Session session = Session.getActiveSession();
if (session != null) {
pendingAction = action;
if (hasPublishPermission()) {
// We can do the action right away.
handlePendingAction();
} else {
// We need to get new permissions, then complete the action when we get called back.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(this, PERMISSIONS));
}
}
}
user.getBirthday();
I remeber using that and storing it as a string.

android facebook sdk - set permissions for openActiveSession

I am trying to integrate Facebook SDK to an android app. I got the code from Facebook manual. It uses Session.openActiveSession and then request a graph user. How could I request for more permissions without using LoginButton class?
Session.openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
if (session.isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
// got user graph
} else {
// could not get user graph
}
}
});
}
}
});
Thank you.
Try this:
mCallback = new Session.StatusCallback() {...}; // the code you already have
Session.OpenRequest request = new Session.OpenRequest(mContext);
request.setPermissions(Arrays.asList("email", "user_birthday"));
request.setCallback(mCallback );
// get active session
Session mFacebookSession = Session.getActiveSession();
if (mFacebookSession == null || mFacebookSession.isClosed())
{
mFacebookSession = new Session(mContext);
Session.setActiveSession(mFacebookSession);
}
mFacebookSession.openForRead(request);
This solves the problem using opensession and extended persmission just once. Facebook SDK 3.5
Session s = new Session(this);
Session.setActiveSession(s);
Session.OpenRequest request = new Session.OpenRequest(this);
request.setPermissions(Arrays.asList("basic_info","email"));
request.setCallback( new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Toast.makeText(getApplicationContext(), "User email is:"+user.getProperty("email"), Toast.LENGTH_SHORT).show(); }
else {
Toast.makeText(getApplicationContext(), "Error User Null", Toast.LENGTH_SHORT).show();
}
}
}).executeAsync();
}
}
}); //end of call;
s.openForRead(request); //now do the request above

Android Facebook native app not getting user email and birthday even with permissions set and correct information in fields

I'm trying to get the user email and birthday (using a Me request). My app has email and user_birthday permissions and the fb account i'm using has an email and a birthday set.
When I try using the 'Graph API Explorer' (https://developers.facebook.com/tools/explorer) using the user access_token with 'fields=id,email,birthday' all I get is the id.
Can anybody advice me on this please.
Here is my code:
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
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) {
// here I check the infos I got.
Log.d("some tag", user.getInnerJSONObject().toString()); // it shows only the id, no email or birthday.
if (Session.getActiveSession() != null) {
Log.i(TAG, "Log out from FB");
Session.getActiveSession().closeAndClearTokenInformation();
}
}
}
});
// set params.
request.getParameters().putString("fields", "id,email,birthday");
// execute request.
request.executeAsync();
Log.d(TAG, request.toString());
}
if (exception != null) {
exception.printStackTrace();
}
}
});
Many thanks.
I finally changed the approach using the OpenRequest instead of getMeRequest:
Here is my code:
public void onClick(View v) {
Logger.d(TAG, "Start FB session");
// check if a session exists.
Session currentSession = Session.getActiveSession();
if (currentSession == null || currentSession.getState().isClosed()) {
// create a new session.
Session session = new Session.Builder(getApplicationContext()).build();
// set it a the active session.
Session.setActiveSession(session);
// keep a variable link to session.
currentSession = session;
}
// if a session is already open then issue a request using the available
// session. Otherwise ask for user credentials.
if (currentSession.isOpened()) {
// The user is logged in.
Logger.e(TAG, "User is logged in.");
Session.getActiveSession().closeAndClearTokenInformation();
Logger.i(TAG, "Session closed an token information cleared.");
// get user data here with no extra call.
Session.openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Logger.i(TAG, "User:" + user.getInnerJSONObject());
}
}
});
}
}
});
} else {
// Ask for username and password
OpenRequest op = new Session.OpenRequest((Activity) this);
// don't use SSO.
op.setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO);
// no callback needed.
op.setCallback(null);
// set permissions.
List<String> permissions = new ArrayList<String>();
permissions.add("email");
permissions.add("user_birthday");
op.setPermissions(permissions);
// open session for read.
currentSession.openForRead(op);
Logger.d(TAG, "Session open for read request issued.");
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Logger.d(TAG, "Request code is: " + requestCode);
Logger.d(TAG, "Result code is: " + resultCode);
super.onActivityResult(requestCode, resultCode, data);
if (Session.getActiveSession() != null)
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
Session currentSession = Session.getActiveSession();
if (currentSession == null || currentSession.getState().isClosed()) {
Session session = new Session.Builder(getApplicationContext()).build();
Session.setActiveSession(session);
currentSession = session;
}
if (currentSession.isOpened()) {
Session.openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Logger.i(TAG, "User:" + user.getInnerJSONObject());
}
}
});
}
}
});
}
}
I hope this helps.
When you are using Request.GraphUserCallback(), its best to use it in MAIN UI THREAD
Session s = Session.getActiveSession();
if(s!=null)
{
Request.executeMeRequestAsync(s,new Request.GraphUserCallback()
{
#Override
public void onCompleted(GraphUser user, Response response)
{
if(user!=null)
{
try {
String fbid=null;
String birthday=null;
fbid=user.getId();
birthday=user.getBirthday();
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}
});
}
you can try this also before the Request.executeMeRequestAsync(...){...}
List<String> permissions = session.getPermissions();
List<String> permissionsBirthday = new ArrayList<String>();
permissionsBirthday.add("user_birthday");
if (!isSubsetOf(permissionsBirthday, permissions)) {
pendingPublishReauthorization = true;
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, permissionsBirthday);
if (setPermissions(session, newPermissionsRequest))
return;
}
the method isSubsetOf();
private boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
hope this helps.
This code worked for me hope you find it useful. This retrieves the user email in 3 different ways and also logs it
try{
// new Read().execute("Facebook");
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
// TextView welcome = (TextView) findViewById(R.id.welcome);
// welcome.setText("Hello " + user.getName() + "!");
Log.d("useremai", (String) user.getProperty("email"));
Log.d("USER", user.getInnerJSONObject().toString());
JSONObject details = user.getInnerJSONObject();
useremail = details.optString("email");
Log.d("name", user.getName());
Log.d("email", useremail);
}
}
});
}
}
});
}catch(NoClassDefFoundError e){
e.printStackTrace();
}
Try this one:
if you have object of user than do below:
if (user != null) {
String UserId = user.getId();
try {
Log.i("Birthdate", ""+user.getInnerJSONObject().getString("birthday"));
} catch (JSONException e) {
e.printStackTrace();
}
}

Facebook SDK 3.0 Android - Token missing

I'm trying to use the facebook authentification in my app but I'm not able to login because the token is missing. In the LogCat I have a loop : "[Tag]System.out [Text]doLogin:".
This happens before the Facebook dialog, and when it appears I click on "Ok" but nothing happens.
Here is my code:
private SharedPreferences.Editor loginPrefsEditor;
private Session.StatusCallback statusCallback = new SessionStatusCallback();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fb_auth);
choosePseudoButton = (Button) findViewById(R.id.buttonChoosePseudoFb);
progressBarFb = (ProgressBar) findViewById(R.id.progressBarFbLoad);
textViewFbInfo = (TextView) findViewById(R.id.currentInfoFb);
editTextFbPseudo = (EditText) findViewById(R.id.editTextPseudoFb);
/*
* Get existing access_token if any
*/
mPrefs = getPreferences(MODE_PRIVATE);
// start Facebook Login
Session.openActiveSession(this, true, new Session.StatusCallback() {
public void call(final Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
System.out.println("onCreate");
fbToken = session.getAccessToken();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putString("access_token", fbToken);
JSONRequest jr = (JSONRequest) new JSONRequest().execute();
}
}
});
}
else {
doLogin();
}
}
});
}
private void doLogin() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
} else {
Session.openActiveSession(this, true, statusCallback);
}
fbToken = session.getAccessToken();
System.out.println("doLogin: "+fbToken);
JSONRequest jr = (JSONRequest) new JSONRequest().execute();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
private void updateView() {
Session session = Session.getActiveSession();
if (session.isOpened()) {
fbToken = session.getAccessToken();
System.out.println("updateView: "+fbToken);
JSONRequest jr = (JSONRequest) new JSONRequest().execute();
}
else {
doLogin();
}
}
private class SessionStatusCallback implements Session.StatusCallback {
public void call(Session session, SessionState state, Exception exception) {
// Respond to session state changes, ex: updating the view
if( session.isOpened() ){
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
public void onCompleted(GraphUser user, Response response) {
}
});
}
updateView();
}
}
Several things to note:
Session opening happens asynchronously, meaning that when you call Session.openActiveSession, it does not (always) immediately open the session (it has to call into another activity, wait for user input, etc). So your line
fbToken = session.getAccessToken();
will almost always return null.
Secondly, there are a few states a Session can be in before it gets to the OPENED state, so in your SessionStatusCallback, you should probably move the updateView() call to be inside the if(session.isOpened()) check.
Lastly, you're calling Session.openActiveSession in the onCreate method, and in that callback, you're always calling doLogin() if the session is not opened. But like I said before, the session can transition to multiple states before it's OPENED, so you're in fact calling doLogin multiple times. Remove that doLogin() call.

Categories

Resources