I am trying to use the Facebook SDK 3.0 to retrieve an access token on button press in my android app. I have a generic button in my Activity that is doing the following:
Button facebook = (Button)findViewById(R.id.facebookLoginButton);
facebook.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Session session = new Session(getApplicationContext());
Session.setActiveSession(session);
session.openForRead(new Session.OpenRequest(SignInActivity.this).setCallback(statusCallback));
}
});
And then the callback:
private class FacebookSessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
String s=session.getAccessToken();
}
}
Clicking the button prompts me for my permission to access my profile as expected, but this callback is only ever called once with SessionState as "OPENING". The state doesn't change after this.
What am I missing here? My end goal is really just to get an access token once, and I don't really care about persisting the session or using it to log into my app.
You need to override the onActivityResult so that after the credentials are checked against Facebook for Android (or an inline login) the results are handled and the session updated. Add the following code:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession()
.onActivityResult(this, requestCode, resultCode, data);
}
#Lucas Jota: Try changing request code. this works for me.
session.openForRead(new Session.OpenRequest(LoginActivity.this).setCallback(statusCallback).setRequestCode(urRequestCode));
Also, assure that your activity doesn't have "single instance" as property.
Related
This code results in the onCompleted method being called on Samsung JELLYBEAN but not on Motorola KITKAT or LG LOLLIPOP devices. The log returns: W/Facebook test(20699): Facebook session status changed - OPENED - Exception: null on all devices.
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
String message = "Facebook session status changed - "
+ session.getState() + " - Exception: " + exception;
Log.w("Facebook test", message);
if (session.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
Log.d("onCompleted","");
}
}).executeAsync();
}
}
}
I have checked permissions and the hashes stored. This is my onActivityResult method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
UPDATE: I created a test project with identical code to the problem app. This project doesn't have the problem, which suggests it isn't a java issue. The manifests are the same with regards to Facebook. I have the correct app_id in each case. The settings of the apps on developers.facebook.com are the same except for package name, class name and key hash.
Go to developers.facebook.com
Select your app
Select Status and Review
Change "Do you want to make this app and all its live features
available to the general public?" to NO
(I waited about ten minutes at this point, which may not be necessary)
Then change the same setting back to YES
I have been working with Facebook SDK for my current android project. I am facing some weird problems during Facebook login for first time, i.e. When i rum my code for the first time it asks for login and once login is successful , a popup appears asks for public profile permission when i agree a loading progress appears on popup endlessly, i cannot even cancel the popup. It does not go back to 'onActivityResult()' method of the calling activity. Ultimately i have to force stop my application.
But once i open my application again on phone now everything works fine and as expected.
I guess it is happening for the first time when application gets registered to facebook.
If i repeat the whole process , i.e. deleting application from facebook, logging out from device's facebook app, and uninstalling and re-installing my application again on phone, i face the same problem.
I am using Facebook SDK 3.5
Here is my code: activity's onCreate(...) method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
TextView welcome = (TextView) findViewById(R.id.welcome);
welcome.setText("Hello " + user.getName() + "!");
}
}
}).executeAsync();
}
}
});
}
onActivityResult(....) method
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println("In on Activity Result");
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
I'm using Facebook Android sdk3.0.
I want to do something after user successfully log in through Facebook.
Should I implement it inside onActivityResult or the onComplete function of Session.StatusCallback?
Actually is there any difference between the two? Can I assume Session.StatusCallback onComplete is always called after onActivityResult ?
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
// Do Something Here?
}
private class SessionStatusCallback implements Session.StatusCallback {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
// Or Do Something Here?
}
}
}
The short answer is, you should do both.
onActivityResult is needed because you need to pass on the information to the Facebook SDK in order for the SDK to verify that the user has accepted the terms and permissions. Once the SDK verifies everything, it will then call the SessionStatusCallback.call with the new state, or any errors that occurred.
When you're opening a new session, it will first transition to the OPENING state (which will call your callback), then it will do the SSO, when SSO completes, your onActivityResult will be called (at which time you should call session.onActivityResult or uiLifecycleHelper.onActivityResult), then the session will transition to the OPENED state, which will call your callback again.
I followed the step of "Create a new Android Project with Facebook Login" section at https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/ The login process is fine. Because I would like to use the native Android button for a user to log in, I modify the code slightly by moving the following code into a View.OnClickListener() of a native Android button. The following is the code in the listener:
Session.openActiveSession(MainActivity.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) {
Toast.makeText(getApplicationContext(), "Hello " + user.getName() +" "+user.getId()+"!", Toast.LENGTH_LONG).show();
}
}
});
}
}
});
The onActivityResult() and AndroidManifest.xml is the same as the tutorial
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
However, I would like to request get "read_friendlists" when a user logs in successfully. I read the tutorial at https://developers.facebook.com/docs/tutorials/androidsdk/3.0/scrumptious/authenticate/ but it uses Facebook SDK customized button. How can I achieve the same behavior with a native Android button like my code shown above?
I just answered a similar question on another post. My solution allows you to use a native button and request additional read permissions when the user first logs in. Check it out here Ask for more permissions with 3.0 SDK
So I have a simple login button that does this in my oncreate:
mLoginButton = (LoginButton)findViewById(R.id.connect_facebook_button);
mLoginButton.setApplicationId(.getResources().getString(R.string.app_id));
mLoginButton.setUserInfoChangedCallback(new LoginButton.UserInfoChangedCallback() {
public void onUserInfoFetched(GraphUser user) {
setUser(user); // Just sets mUser to be this user
try {
Toast.makeText(this, mUser.getFirstName(), Toast.LENGTH_SHORT).show();
} catch (Exception FacebookException) {
FacebookException.printStackTrace();
}
}
});
All of that is called successfully, including the onUserInfoFetched.
The problem is, in every instance, my Graphuser user is null.
My appID is correct, my android hash is the debug one that they give me (tested on sample apps worked fine), the login screen does actually pop up... Not really sure where to go from here.
Also, if I hit the button twice, I get an error:
an attempt was made to open a session that has a pending request
Whoops! Forgot my activity result!
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
That did the trick.