Why Facebook Session state is always close? - android

I want to add Facebook login functionality into my app. Please note that:
I don't want to use Facebook login button widget.
I copy pasted my code that was working correctly last year (from my other project) into my new project.
I checked Session page and I guess I have no problem.
The only difference was Request.executeMeRequestAsync() hss changed to Request.newMeRequest(). I did this change but seems my session is always close although I could see Session.setActiveSession(session); method runs by debug of project. So, have no idea really why session is always close in call() method.
Any idea would be appreciated. Thanks.
My code:
public class FacebookLogin extends FragmentActivity
{
private static final String TAG = "FacebookLogin";
private static final List<String> READ_PERMISSIONS =
Arrays.asList("email", "user_about_me", "user_photos");
// private static final List<String> WRITE_PERMISSIONS = Arrays.asList("");
private final Session.StatusCallback statusCallback = new Session.StatusCallback()
{
#Override
public void call(final 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)
{
MyLog.d(TAG, "User name: " + user.getName() + "!, Login successfully :)");
MyLog.d(TAG, "User id: " + user.getId());
MyLog.d(TAG, "Access token is: " + session.getAccessToken());
MyLog.d(TAG, "Application id: " + session.getApplicationId());
MyLog.d(TAG, "JSON Object: " + user.getInnerJSONObject());
SpStorage.setKeyFacebook(FacebookLogin.this, session.getAccessToken());
SpStorage.setFacebookUserId(FacebookLogin.this, user.getId());
// erson person = parseJSON(user.getInnerJSONObject().toString());
// registerUser();
// Close activity
FacebookLogin.this.finish();
}
}
});
request.executeAsync();
}
else if (state.isClosed()) {
MyLog.d(TAG, "Facebook session closed");
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Find device hash key (should not be used in production)
// printHashKey();
// start Facebook Login
openActiveSession(this, true, statusCallback, READ_PERMISSIONS);
}
private static Session openActiveSession(Activity activity, boolean allowLoginUI,
Session.StatusCallback callback, List<String> permissions)
{
Session.OpenRequest openRequest = new Session
.OpenRequest(activity)
.setPermissions(permissions)
.setCallback(callback);
Session session = new Session.Builder(activity).build();
if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI)
{
Session.setActiveSession(session);
session.openForRead(openRequest);
return session;
}
return null;
}
}
What I get in logcat:
Facebook session closed

You need to override the onActivityResult method in your Fragment class and pass it on to the session in order to complete the session transitions.
This needs to happen regardless of whether you're using the UiLifecycleHelper or not.

You need to override onActivityResult and pass the values to the facebook SDK.
From Facebook's SDK docs:
To ensure that the sessions are set up correctly, your fragment must
override the fragment lifecycle methods: onCreate(), onResume(),
onPause(), onDestroy(), onActivityResult() and onSaveInstanceState()
and call the corresponding UiLifecycleHelper methods. For example,
calling the onCreate() method in the UiLifecycleHelper object creates
the Facebook session and opens it automatically if a cached token is
available.

Recently Facebook is using API V2.2 and it has deleted some methods.
recently Before 1 week i have done some for getting user information.
Which may be helping you.
public void getProfileData(View button){
Session activeSession = Session.getActiveSession();
new Request(
activeSession,
"me",
null,
HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
/* handle the result */
try
{ GraphObject go = response.getGraphObject();
JSONObject jso = go.getInnerJSONObject();
String name23 = jso.getString("name");
Log.e("Name response",""+name23);
name = name23;
Toast.makeText(getApplicationContext(), "Name: " + name , Toast.LENGTH_LONG).show();
}
catch ( Throwable t )
{
t.printStackTrace();
}
String name = response.toString();
Log.e("Name request",""+name);
}
}
).executeAsync();
}

Related

Android & Facebook SDK: Obtain user data without Login Button

I am losing my mind trying to integrate Facebook with an app. First of all, Fb's SDK is terrible and its making everything crash since I included it. Anyway, I am trying to obtain user data from Facebook, just his/her name, user id and email; however, I can't use the Login Button because it doesn't support Nested Fragments and it uses UiLifecycleHelper which keeps a Session open and keeps executing a callback that I only want to call once.
I don't need to keep a Session open; I will sporadically open Sessions the first time the user uses the app and if he/she wants to publish something (very rare).
So far I have tried using the Login Button, performing a simple Request and combining both. However, it seems that the SDK as a whole doesn't play very well with Nested Fragment.
This was my last attempt at making this work (these two methods are inside a Fragment. Once a button is pressed, performFacebookLogin is executed):
public void performFacebookLogin() {
Session.openActiveSession(getActivity(), true, Arrays.asList("email"), new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.d("FACEBOOK", "Session has been opened");
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
Log.d("FACEBOOK", "onCompleted");
if (user != null) {
Log.d("DBG", buildUserInfoDisplay(user));
}
}
}).executeAsync();
}else{
//TODO: ERROR
Log.e("FACEBOOK", "Session could not be opened");
}
}
});
}
private String buildUserInfoDisplay(GraphUser user) {
StringBuilder userInfo = new StringBuilder("");
userInfo.append(String.format("Name: %s\n\n",
user.getName()));
userInfo.append(String.format("Email: %s\n\n",
user.getProperty("email")));
userInfo.append(String.format("ID: %s\n\n",
user.getId()));
return userInfo.toString();
}
So, what happens? The dialog prompt is shown in order to login using your Facebook account. But, once you press Login and the dialog disappears, nothing happens. Nothing is shown in the LogCat. I think is a problem with the onActivityResult method, because the callback is never executed. I tried re-adding the UiLifecycleHelper, but it ends up making unwanted calls to the callback (I only want to call this method once).
You are correct, you need to plumb the result through to the active Session for your callback to be activated. In your activities onActivityForResult method, call the active sessions onActivityResult, similar to this: https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/UiLifecycleHelper.java#L156-159
Session session = Session.getActiveSession();
if (session != null) {
session.onActivityResult(activity, requestCode, resultCode, data);
}
That would get your callback working.
So, I managed to achieve a modular approach to my problem: I created an activity that encapsulated the connection to Facebook's SDK and returns it via onActivityResult. Unfortunately, I haven't found a way to return the result to a nested fragment directly.
On a side note, you can make the activity transparent to avoid a black screen and add more permissions if you need them. Also, you can remove the onStop method if you want to keep the Session active.
Here's the code:
public class FacebookAccessActivity extends ActionBarActivity {
public static final String PARAM_PROFILE = "public_profile";
public static final String PARAM_EMAIL = "email";
public static final String PARAM_FIRSTNAME = "fname";
public static final String PARAM_LASTNAME = "lname";
public static final String PARAM_GENDER = "gender";
public static final String PARAM_BDAY = "user_birthday";
public static final String PARAM_ID = "id";
private static Session session = null;
private List<String> permissions = Arrays.asList(PARAM_EMAIL, PARAM_PROFILE, PARAM_BDAY);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.view_empty);
session = Session.getActiveSession();
if (session != null)
session.closeAndClearTokenInformation();
Session.openActiveSession(this, true, permissions, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (exception != null || state == SessionState.CLOSED_LOGIN_FAILED) {
exception.printStackTrace();
setResult(RESULT_CANCELED);
finish();
} else if (session.isOpened()) {
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Intent i = new Intent();
i.putExtra(PARAM_FIRSTNAME, user.getFirstName());
i.putExtra(PARAM_LASTNAME, user.getLastName());
i.putExtra(PARAM_ID, user.getId());
i.putExtra(PARAM_GENDER, (String) user.getProperty(PARAM_GENDER));
i.putExtra(PARAM_BDAY, user.getBirthday());
for (String s : permissions)
i.putExtra(s, (String) user.getProperty(s));
setResult(RESULT_OK, i);
finish();
}
}
}).executeAsync();
}
}
});
}
#Override
protected void onStop() {
super.onStop();
if (session != null)
session.closeAndClearTokenInformation();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_CANCELED ||
!Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data)) {
setResult(RESULT_CANCELED);
finish();
}
}

Android FacebookSDK get Birthday

I have created sample app with facebook sdk integration. Now I can Login with facebook Also get some basic information from facebook. But fail to got birthday from "GraphUser" I have noticed that for birthday I need to set permission "user_birthday" which I have already set. I couldn't get what wrong with response.
private static Session openActiveSession(Activity activity, boolean allowLoginUI, Session.StatusCallback callback, List permissions) {
Session.OpenRequest openRequest = new Session.OpenRequest(activity).setPermissions(permissions).setCallback(callback);
Session session = new Session.Builder(activity).build();
if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) {
Session.setActiveSession(session);
session.openForRead(openRequest);
return session;
}
return null;
}
private void startFacebookLogin() {
openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
//make request to the /me API
Log.e("sessionOpened", "true");
Request.newMeRequest(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
String firstName = user.getFirstName();
String lastName = user.getLastName();
String id = user.getId();
String email = user.getProperty("email").toString();
Log.d("AllData", user.toString());
Log.e("facebookId", id);
Log.e("firstName", firstName);
Log.e("lastName", lastName);
Log.e("email", email);
String Birthdate=user.getBirthday();
Log.e("Birthdate", Birthdate+"::Birthdate");
}
}
}).executeAsync();
}
}
}, Arrays.asList(
new String[] { "email", "user_location", "user_birthday","user_likes" }));
}
GraphUser respose is
GraphObject{graphObjectClass=GraphUser, state={"id":"…..","first_name":"…..","timezone":5.5,"email":"…..#gmail.com","verified":false,"name":"…..","locale":"en_US","link":"https:\/\/www.facebook.com\/app_scoped_user_id\/....\/","last_name":"…..","gender":"male","updated_time":"2012-12-21T06:54:19+0000"}}
Are you trying this with an admin/tester/developer user of your Facebook app? If not, the reason is that if you request extended permissions, you'll need to get your app through the Facebook app review process, as described here:
https://developers.facebook.com/docs/apps/review/login#do-you-need-review

Graph User returning Null, even though the session is created

I have been trying to integrate facebook to my app, but it always returns a Null Graph user.I tried adding the onActivityResult method as a solution told here, but still doesn't seem to help.
public class FacebookRegistartionActivity extends FragmentActivity
{
private Session.StatusCallback mStatusCallback = new SessionStatusCallback();
// private static final int REQUEST_CODE_SIGN_IN = 1;
Session session;
#Override
protected void onCreate(Bundle arg0) {
// TODO Auto-generated method stub
super.onCreate(arg0);
fbRegistration();
}
public void fbRegistration() {
Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
session = Session.getActiveSession();
Log.i("", "Session before : "+session);
if (session == null) {
session = new Session(FacebookRegistartionActivity.this);
if (session != null) {
Session.setActiveSession(session);
if (session != null && !session.isOpened()&& !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(mStatusCallback));
} else {
}
}
} else {
Log.i("", "Session null ... : "+session);
// start Facebook Login
Session.openActiveSession(this, true, mStatusCallback);
}
}
The code doesn't even reach the onActivityResult() method.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.i("", "requestCode : "+requestCode);
Log.i("", "resultCode : "+resultCode);
Log.i("", "data : "+data);
if (resultCode == RESULT_OK) {
Session.getActiveSession().onActivityResult(this, requestCode,resultCode, data);
}
}
private class SessionStatusCallback implements Session.StatusCallback {
// callback when session changes state
#Override
public void call(Session session, SessionState state,
Exception exception) {
Log.i("", "session in on status call back....."+session);
// Here the session is there, not null
if (session.isOpened()) {
Log.i("", "session is opened....."+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(final GraphUser user, Response response) {
Log.i("in SignUp", "USER :: " + user);
// Log.i("in SignUp", "response :: " + response);
if (user != null) {
try{
String fqlQuery = "select url from profile_pic where id=me() and width=200 and height=200";
Bundle params1 = new Bundle();
params1.putString("q", fqlQuery);
Session session = Session.getActiveSession();
Request request = new Request(session, "/fql", params1,
HttpMethod.GET, new Request.Callback() {
public void onCompleted(Response response) {
try {
String serverresponse=response.getGraphObject().getInnerJSONObject().toString();
Log.e("serverresponse", ""+serverresponse);
JSONObject jsonobj=new JSONObject(serverresponse);
JSONArray array=jsonobj.getJSONArray("data");
Log.e("","data object : "+array);
jsonobj = array.getJSONObject(0);
String fbUserImageUrl = jsonobj.getString("url");
Log.e("","image url : "+fbUserImageUrl);
Logger.show(Log.INFO, "", " AccessToken with publish stream:: " +Session.getActiveSession().getAccessToken());
String uniqueId = user.getId();
String userName = user.getName();
String image = fbUserImageUrl; //"http://graph.facebook.com/"+user.getId()+"/picture?type=large";
String emailId = user.asMap().get("email").toString();
Logger.show(Log.INFO,"","uniqueId :: "+ uniqueId);
Logger.show(Log.INFO,"","userName :: "+ userName);
Logger.show(Log.INFO,"","image :: "+ image);
Logger.show(Log.INFO,"","emailId :: "+ emailId);
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
Request.executeBatchAsync(request);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
else
{
Log.i("", "Graph user null");
// Always the Graph user is returning Null
}
}
}).executeAsync();
}
else
{
Log.i("", "Session not opened still.....");
}
}
}
}
EDIT :
I checked for answers, then realized, I just missed to add the permissions into the Android Manifest file.
Just realized! I Did everything except adding the following permission in Android Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
But, Still wonder how I was able to get the session. Means, it does not require a net connection? Taken in to account that the device I tested had the facebook app installed in it.
Is the session provided by the facebook app, instead? Wished to know how the facebook app works in the login flow in our app, using the facebook sdk.
Any help regarding this is appreciated.
As I have mentioned in comment - Yes it is true that when a facebook Session object is created, it attempts to initialize itself from a TokenCachingStrategy. But there must be a Session token cache. As you have told that you were using same app id from some other app, the app was authorized by the user and the session was created and saved in the cache.
Because facebook manages session based on the app id and as the session was already created it fetched it from cache for your new app. But for fetching graph user when you call Request.newMeRequest, it is making an internet connection, since the internet permission was not there in the manifest, your app was not able to connect to facebook server to fetch the same.

how to get email id from facebook sdk in android applications?

I integrated Facebook login in my android application. I want to get email id of login user. How will I get it?
private void loginToFacebook() {
Session.openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
Log.i(TAG, "Access Token" + session.getAccessToken());
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
try {
userID =user.getId();
provider="facebook";
userName=user.getUsername();
firstName=user.getFirstName();
lastName=user.getLastName();
Log.d("****User****", "details:" + user);
}catch(Exception e){
Here is my code. i use Request.GraphUserCallback() method but there is no response of email from this method.
Before calling Session.openActiveSession do this to get permissions add this:
List<String> permissions = new ArrayList<String>();
permissions.add("email");
The last parameter in Session.openActiveSession() should be permissions.
Now you can access user.getProperty("email").toString().
EDIT:
This is the way I am doing facebook authorization:
List<String> permissions = new ArrayList<String>();
permissions.add("email");
loginProgress.setVisibility(View.VISIBLE);
//start Facebook session
openActiveSession(this, true, new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if (session.isOpened()) {
//make request to the /me API
Log.e("sessionopened", "true");
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
String firstName = user.getFirstName();
String lastName = user.getLastName();
String id = user.getId();
String email = user.getProperty("email").toString();
Log.e("facebookid", id);
Log.e("firstName", firstName);
Log.e("lastName", lastName);
Log.e("email", email);
}
}
});
}
}
}, permissions);
Add this method to your activity:
private static Session openActiveSession(Activity activity, boolean allowLoginUI, Session.StatusCallback callback, List<String> permissions) {
Session.OpenRequest openRequest = new Session.OpenRequest(activity).setPermissions(permissions).setCallback(callback);
Session session = new Session.Builder(activity).build();
if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) {
Session.setActiveSession(session);
session.openForRead(openRequest);
return session;
}
return null;
}
Following the suggestion of Egor N, I change my old code
Session.openActiveSession(this, true, statusCallback);
whith this new one:
List<String> permissions = new ArrayList<String>();
permissions.add("email");
Session.openActiveSession(this, true, permissions, statusCallback);
Now FB ask the user about the permission of email and I can read it in the response.
Try this article. Hope your issues will be solved Click Here
Btw, You need to use user.asMap().get("email").toString()); for receving the User Email ID.
Also, you need to assign that into some of label like lblEmail.setText where lblEmail is a Textview.

How to get the Facebook Friendlist using Intent in Android?

I would like to get the friendlist of the facebook using intent.
Please let me know if there is any way to get the friends list of the facebook by using built in application of the device.
Thanks.
You need to integrate the Android SDK into your app, here is the link to download the latest SDK. You then will have to have the user authenticate your app to access their information.
Here is sample code to do this
private SessionTracker mSessionTracker;
private Session mCurrentSession;
private void signInWithFacebook() {
mSessionTracker = new SessionTracker(getBaseContext(), new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
}
}, null, false);
String applicationId = Utility.getMetadataApplicationId(getBaseContext());
mCurrentSession = mSessionTracker.getSession();
if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
mSessionTracker.setSession(null);
Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
Session.setActiveSession(session);
mCurrentSession = session;
}
if (!mCurrentSession.isOpened()) {
Session.OpenRequest openRequest = null;
openRequest = new Session.OpenRequest(SignUpChoices.this);
if (openRequest != null) {
openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS);
openRequest.setPermissions(Arrays.asList("user_birthday", "email", "user_location"));
openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
mCurrentSession.openForRead(openRequest);
Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
Log.w("myConsultant", user.getId() + " " + user.getName() + " " + user.getInnerJSONObject());
}
});
}
}
}
One you have a user that has approved your app you can perform other Request about their information. friends info example
Finally i found a way to get the friendlist of the Facebook using Intent.
Intent m_fb=getOpenFacebookIntent(m_context);
startActivity(m_fb);
public static Intent getOpenFacebookIntent(Context context) {
try {
context.getPackageManager().getPackageInfo("com.facebook.katana", 0);
return new Intent(Intent.ACTION_VIEW,Uri.parse("fb://profile/<user_id>/fans"));
} catch (Exception e) {
return new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/abc.xyz"));
}
}
You can use Official Facebook App with Intent listed HERE.

Categories

Resources