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);
}
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 am using restfb API to access my friend's photos in Java. And to access these photos, I generate access code manually using Graph API explorer and pass this as a parameter to the restfb API call.
But now I want to generate this access token through code (programmatically). I have seen fb android samples, particularly hackbook. I don't see any access code being generated which I can use for my own application. Do I need to create a new app and get some secret etc? Any suggestion will be appreciated.
I have seen these solutions (solution-1 & solution-2) on stackoverflow but I am still not getting where to start?
Update-1::
I am using following code to login and getting access token for logged in user. But the problem is that it only works for the account with which I had created an app on facebook to generate an app_id. It does not get a call back for other accounts. Any suggestion please.
And just in case if you don't know where to start, follow step-6 to create a new app from scratch.
public class MainActivity extends Activity implements OnClickListener {
Button login;
TextView accessToken;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
login = (Button) findViewById(R.id.login);
accessToken = (TextView) findViewById(R.id.accessToken);
login.setOnClickListener(this);
// start Facebook Login
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#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()
{
Session session = Session.getActiveSession();
if(session != null)
if (session.isOpened()) {
//Toast.makeText(this, session.getAccessToken(), Toast.LENGTH_LONG).show();
accessToken = (TextView) findViewById(R.id.accessToken);
accessToken.setText(session.getAccessToken());
System.out.println("----------------------" + session.getAccessToken() + "---------------------");
}
super.onResume();
}
#Override
public void onClick(View v) {
// start Facebook Login
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() + "!");
}
}
});
}
}
});
}
}
Using the Facebook SDK the better way to manage the authentication of the user is by means of the Session class.
When you have a valid instance of the Session class you just have to call the getAccessToken() on it in order to obtain the String representing the access token.
Session session = Session.getActiveSession();
if (session != null && session.getState().isOpened()){
Log.i("sessionToken", session.getAccessToken());
Log.i("sessionTokenDueDate", session.getExpirationDate().toLocaleString());
}
I was having the same problem using the latest Facebook Android SDK (4.0.1).
I used AccessToken.getCurrentAccessToken() and it worked:
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(),
new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject jsonObject, GraphResponse response) {
Log.d(LOG_TAG,"onCompleted jsonObject: "+jsonObject);
Log.d(LOG_TAG,"onCompleted response: "+response);
// Application code
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,cover,email");
request.setParameters(parameters);
request.executeAsync();
GET /oauth/access_token?
client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
Answer to the original question has already been entered as update-1. But it was only working for admin users.
Actually during app creation, I had wrongly selected 'sandboxed' mode which restricts app's access only to developers added in app configuration page. So after disabling this mode, I was able to generate access token for other users too.
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
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.
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.