I am currently using sessions to log user into Facebook.
private Session createSession() {
Session activeSession = Session.getActiveSession();
if (activeSession == null || activeSession.getState().isClosed()) {
activeSession = new Session.Builder(this).setApplicationId(APP_ID).build();
Session.setActiveSession(activeSession);
}
return activeSession;
}
It is so far simple and straight forward. Is there a way to modify permissions in a similar way, or do i absolutely need to use the Login Button.
to be specific-
I wish to get user notification. So I need extended permission manage_notifications.
Related
How to check whether user has logged into facebook native app using facebook sdk from our android app(as iphone checks the status from settings app)?
without using any server calls
try using facebook Session ....
Session fb_session= null;
fb_session = Session.getActiveSession();
if( fb_session != null )
{
if( fb_session.isOpened() )
{
//do your stuff here......
}
}
Hope it helps...!
I use com.facebook.widget.UserSettingsFragment to manage login/logout to Facebook in my app:
UserSettingsFragment userSettingsFragment = new UserSettingsFragment();
Session session = Session.getActiveSession();
if(session==null || session.isClosed()){
userSettingsFragment.setPublishPermissions(Arrays.asList("publish_actions"));
}
fragmentTransaction.replace(R.id.content_container, userSettingsFragment, "userSettingsFragment");
In another Fragment (but same Activity), Before publishing on Facebook I'm checking whether I'm logged using
Session session = Session.getActiveSession();
if (session != null && session.isOpened()){
publishOnFacebook(intent.getExtras());
}
When I start my app and try to publish, I always get a null Session although I logged in before. And when I start UserSettingsFragment, it shows me that I'm connected.
How can Session.getActiveSession(); be null if I'm actually connected?
Moreover, if I I start the Fragment where I do the publishing straight after UserSettingsFragment, I get the correct Session, i.e.:
1 start the app
2 call `Session.getActiveSession()` in another `Fragment` returns `null`
3 start `UserSettingsFragment` shows that I'm log
but
1 start the app
2 start `UserSettingsFragment` shows that I'm log
3 call `Session.getActiveSession()` in another `Fragment` returns a session
Anybody can help?
Ok, I've just read about openActiveSessionFromCache (not from Facebook doc though):
Session session = Session.getActiveSession();
if(session==null){
// try to restore from cache
session = Session.openActiveSessionFromCache(getActivity());
}
if(session!=null && session.isOpened()){
publishOnFacebook(intent.getExtras());
}
else{
login();
}
Jul's answer does not work for me. So I tried this:
If you had loggedin earlier and if you restarted the app then the session may not be null and it could be in the CREATED_TOKEN_LOADED state. This state implies that the Session has not yet been opened and has a cached token. Opening a Session in this state will not involve user interaction. To open the session from this state you can call the method session.openForRead(null). This immediately opens the session without any user interaction.
So check for this add the following code:
Session session = Session.getActiveSession();
if (session != null){
if(session.getState() == SessionState.CREATED_TOKEN_LOADED){
//this immediately opens the session
session.openForRead(null);
}
if(session.isOpened()) {
publishOnFacebook(intent.getExtras());
}
else{
//start the facebook login fragment or activity
login();
}
}
else{
login();
}
In the Facebook Android SDK when I call
Session tempSession = new Builder(this).build();
Session.setActiveSession(tempSession);
tempSession.openForRead(new OpenRequest(this).setPermissions(FB_PERMISSIONS));
It gets a FB session and every thing runs as normal. But when I replace Read with Publish. i.e. follows
Session tempSession = new Builder(this).build();
Session.setActiveSession(tempSession);
tempSession.openForPublish(new OpenRequest(this).setPermissions(FB_PERMISSIONS));
It gives an error saying, that the session is empty, and cannot get publish permissions to empty session.
Can you please tell why is it like this and what would be the best way to handle this?
It took me a while to sort this out so a user could click a button to share one of my products on Facebook in a feed. I didn't want them to be prompted to sign in until they actually wanted to share, so I really just wanted publish permission. The following stacks the initial login/read permission request with the publish permission request. This will double-prompt the users, first for read, then for publish, but that is required now regardless of the solution:
Session session = Session.getActiveSession();
if (session == null) {
session = new Session.Builder(this).setApplicationId("<APP ID HERE>").build();
Session.setActiveSession(session);
session.addCallback(new StatusCallback() {
public void call(Session session, SessionState state, Exception exception) {
if (state == SessionState.OPENED) {
Session.OpenRequest openRequest = new Session.OpenRequest(FacebookActivity.this);
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
session.requestNewPublishPermissions(
new Session.NewPermissionsRequest(FacebookActivity.this, PERMISSIONS));
}
else if (state == SessionState.OPENED_TOKEN_UPDATED) {
publishSomething();
}
else if (state == SessionState.CLOSED_LOGIN_FAILED) {
session.closeAndClearTokenInformation();
// Possibly finish the activity
}
else if (state == SessionState.CLOSED) {
session.close();
// Possibly finish the activity
}
}});
}
if (!session.isOpened()) {
Session.OpenRequest openRequest = new Session.OpenRequest(this);
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
session.openForRead(openRequest);
}
else
publishSomething();
The short answer is, don't call openForPublish. Call openForRead, and then requestNewPublishPermissions later if you need publish permissions.
The long answer is, you can't request publish permissions (on a user who's never connected with Facebook before via your app) unless you already have basic or default permissions already (what you would get if you call openForRead with an empty permission set). So openForPublish actually handles a very specific niche use case that most apps probably don't have.
I am trying to implement the new Facebook SDK 3.0 into my Android app and I have run into a problem. The problem I am having is that the user is asked to log in again to give publish ("post_to_wall") permissions, even though the user is already logged in, with read permissions. This only happens if the user doesn't have the FB application installed. If he has the FB application installed, then he is only asked to grant the permissions.
This is how I implemented the login:
public void login(Activity activity) {
Session session = Session.getActiveSession();
if (session == null || !session.isOpened()) {
openActiveSession(activity, true, sessionStatusCallback);
}
}
private Session openActiveSession(final Activity activity, final boolean allowLoginUI, final StatusCallback callback) {
return openActiveSession(activity, allowLoginUI, new OpenRequest(activity).setCallback(callback));
}
private Session openActiveSession(final Context context, final boolean allowLoginUI, final OpenRequest openRequest) {
Session session = new Builder(context).setApplicationId(FACEBOOK_APPLICATION_ID).build();
if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) {
Session.setActiveSession(session);
session.openForRead(openRequest);
return session;
}
return null;
}
This is the callback's call method:
public void call(final Session session, final SessionState state, final Exception exception) {
if (session.isOpened()) {
if (state.equals(SessionState.OPENED_TOKEN_UPDATED)) {
// code if new permissions have been granted
} else {
// code for login
}
} else if (session.isClosed()) {
// code for user canceled login
} else if (exception != null) {
// code if there were errors during login
}
}
}
This is the code I added to onActivityResult method of the activity that calls the login:
Session.getActiveSession().onActivityResult(activity, requestCode, resultCode, data);
And this is how I ask for new permissions:
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
if (DONT_HAVE_PERMISSIONS) {
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(activity,
FACEBOOK_PERMISSIONS).setRequestCode(FACEBOOK_AUTHORIZE_ACTIVITY_CODE);
session.requestNewPublishPermissions(newPermissionsRequest);
}
}
I've tried to find out more about this problem, and I only found out some hints that this is intended, but I haven't found anything concrete.
Is this the default behavior? If so, is there a way around it? Or, perhaps I did something wrong?
Thanks for the help.
Update your SDK version; this issue is resolved in Facebook Android SDK v3.0.1.
Looking at facebooks source code I think it should be possible to start trying to get the permissions directly as both login, and permissions classes derive from the same AuthorizationRequest class, and the AuthorizationRequest class does all the work, like really all the work. The Session.NewPermissionsRequest class just makes some private methods, public in the AuthorizationRequest class and that's it! They might as well give us access to AuthorizationRequest directly. The new facebook API doesn't seem to have any form of "OnFailed/OnSuccess" callbacks, so I end up having a state machine to remember the goal of firing up facebook (login, permissions, get friends list ...), and which step I'm on. If they have done some form of onFailed/onSuccess callbacks it would be simple to make a chain rather than keeping track of a state machine.
I haven't tried what I said. If I do, I'll update the answer. If you try and it works to just fire up Session.NewPermissionsRequest directly without logging in let me know!
Update
I got it working with only asking for credentials once as I explained above.
goto src/com/facebook/Sessions.java
On line 862 you will find
private static Session openActiveSession(Context context, boolean allowLoginUI, OpenRequest openRequest)
make it be a public function and save.
Now instead of creating the Session.NewPermissionsRequest object. Make Session.OpenRequest
permisions = new ArrayList<String>();
permisions.add("user_photos");
permisions.add("friends_photos");
Session.NewPermissionsRequest request = new Session.NewPermissionsRequest(
activity, permisions);
request.setCallback(helper);
if (Session.getActiveSession() != null)
Session.getActiveSession().requestNewReadPermissions(request);
else {
Session.OpenRequest orequest = new Session.OpenRequest(activity);
orequest.setPermissions(permisions);
orequest.setCallback(helper);
// its now public so you can call it
Session.openActiveSession(act, true, request);
}
Now make sure you do set a callback, for one important reason
#Override
public void call(Session session, SessionState state, Exception exception) {
if (state.isClosed()) {
// we are doing unofficial stuff so we loose guarantees.
// Set the active session to null if we logout or user cancels
// logging in. If you don't do this, the second time it will result
// in a crash.
Session.setActiveSession(null);
}
}
Now it will ask for all permissions directly and login in one go.
I'm have a feature on my Android app where the user authorizes the app and shares a link.
I also need to give an option for the user to logout of facebook and I need to conditionally disable this button if the user is not logged int (or not authorized the app).
I can't seem to find the API call on the Android SDK that would let me ask FB if the user is logged in or not.
What I have found is getAccessExpires():
Retrieve the current session's expiration time (in milliseconds since
Unix epoch), or 0 if the session doesn't expire or doesn't exist.
Will checking if the session equals 0 be the way to go? Or is there something I'm missing?
Facebook SDK 4.x versions have a different method now:
boolean loggedIn = AccessToken.getCurrentAccessToken() != null;
or
by using functions
boolean loggedIn;
//...
loggedIn = isFacebookLoggedIn();
//...
public boolean isFacebookLoggedIn(){
return AccessToken.getCurrentAccessToken() != null;
}
Check this link for better reference https://developers.facebook.com/docs/facebook-login/android
check this heading too "Access Tokens and Profiles" it says "You can see if a person is already logged in by checking AccessToken.getCurrentAccessToken() and Profile.getCurrentProfile()
I struggled to find a simple answer to this in the FB docs. Using the Facebook SDK version 3.0 I think there are two ways to check if a user is logged in.
1) Use Session.isOpened()
To use this method you need to retrieve the active session with getActiveSession() and then (here's the confusing part) decipher if the session is in a state where the user is logged in or not. I think the only thing that matters for a logged in user is if the session isOpened(). So if the session is not null and it is open then the user is logged in. In all other cases the user is logged out (keep in mind Session can have states other than opened and closed).
public boolean isLoggedIn() {
Session session = Session.getActiveSession();
return (session != null && session.isOpened());
}
There's another way to write this function, detailed in this answer, but I'm not sure which approach is more clear or "best practice".
2) Constantly monitor status changes with Session.StatusCallback and UiLifecycleHelper
If you follow this tutorial you'll setup the UiLifecycleHelper and register a Session.StatusCallback object with it upon instantiation. There's a callback method, call(), which you override in Session.StatusCallback which will supposedly be called anytime the user logs in/out. Within that method maybe you can keep track of whether the user is logged in or not. Maybe something like this:
private boolean isLoggedIn = false; // by default assume not logged in
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (state.isOpened()) { //note: I think session.isOpened() is the same
isLoggedIn = true;
} else if (state.isClosed()) {
isLoggedIn = false;
}
}
};
public boolean isLoggedIn() {
return isLoggedIn;
}
I think method 1 is simpler and probably the better choice.
As a side note can anyone shed light on why the tutorial likes to call state.isOpened() instead of session.isOpened() since both seem to be interchangeable (session.isOpened() seems to just call through to the state version anyway).
Note to readers: This is now deprecated in the new FB 3.0 SDK.
facebook.isSessionValid() returns true if user is logged in, false if not.
Session.getActiveSession().isOpened()
returns true if user is logged in, false if not
Android Studio with :
compile 'com.facebook.android:facebook-android-sdk:4.0.1'
then check login like as:
private void facebookPost() {
//check login
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken == null) {
Log.d(TAG, ">>>" + "Signed Out");
} else {
Log.d(TAG, ">>>" + "Signed In");
}
}
#diljeet was right. https://stackoverflow.com/a/29375963/859330
In addition, use
return AccessToken.getAccessToken() != null && Profile.getCurrentProfile()!=null;
It always works this way.
For Facebook Android SDK 4.x you have to use the "AccessToken.getCurrentAccessToken()" as said by #Diljeet but his check didn't work for me, I finally checked it by doing:
Activity "onCreate":
facebookAccessToken = AccessToken.getCurrentAccessToken();
To check if the session is still active (I made it in the "onResume" method but do it where you need):
if(facebookAccessToken != null){
sessionExpired = facebookAccessToken.isExpired();
}else{
sessionExpired = true;
}
More info in https://developers.facebook.com/docs/facebook-login/android
This seems to be working quite well with the new sdk.
private boolean isFacebookLoggedIn(){
Session session = Session.getActiveSession();
if (session != null) {
//Session can be open, check for valid token
if (!session.isClosed()) {
if(!session.getAccessToken().equalsIgnoreCase("")){
return true;
}
}
}
return false;
}
I had the same issue. Here is my solution using SDK 4.0:
First of all, in your activity dealing with login check, be sure to call this primary:
FacebookSdk.sdkInitialize(this.getApplicationContext());
In your onCreate method put this :
updateWithToken(AccessToken.getCurrentAccessToken());
new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) {
updateWithToken(newAccessToken, handler);
}
};
Then add the method called:
private void updateWithToken(AccessToken currentAccessToken) {
if (currentAccessToken != null) {
fillUIWithFacebookInfos(handler);
} else {
login();
}
}
This way will handle the already logged in user and the newly logged in user.
I was using FB sdk for just for login..
Facebook developers reject my app, Because whenever user login, I send logout.. I dont matter user profile data... I just use FB for login.. FB tells if user login... dont send lgout...
I find Hacking way...
Now my app doesnot send logout whenever user login.... Whatever user login with,Google,Facebook,or normal.. When they click logout... In this three condition
I use
LoginManager.getInstance().logOut();
No matter which platform they use... There is no crash :)