With Facebook's new Android SDK 3.0 (that was released a few days ago), the process of authentication has changed.
So how do you request a read permission such as "friends_hometown"?
The following code is how I am trying to do it - but I'm quite sure it's not the way you should do this:
Version 1:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Session.openActiveSession(this, true, new Session.StatusCallback() { // start Facebook login @Override public void call(Session session, SessionState state, Exception exception) { // callback for session state changes if (session.isOpened()) { List<String> permissions = new ArrayList<String>(); permissions.add("friends_hometown"); session.requestNewReadPermissions(new Session.NewPermissionsRequest(FBImport.this, permissions)); Request.executeGraphPathRequestAsync(session, "me/friends/?access_token="+session.getAccessToken()+"&fields=id,name,hometown", new Request.Callback() { ... }); } } }); }
Version 2:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Session currentSession = Session.getActiveSession(); if (currentSession == null || currentSession.getState().isClosed()) { Session session = Session.openActiveSession(this, true, fbStatusCallback); // PROBLEM: NO PERMISSIONS YET BUT CALLBACK IS EXECUTED ON OPEN currentSession = session; } if (currentSession != null && !currentSession.isOpened()) { OpenRequest openRequest = new OpenRequest(this).setCallback(fbStatusCallback); // HERE IT IS OKAY TO EXECUTE THE CALLBACK BECAUSE WE'VE GOT THE PERMISSIONS if (openRequest != null) { openRequest.setDefaultAudience(SessionDefaultAudience.FRIENDS); openRequest.setPermissions(Arrays.asList("friends_hometown")); openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK); currentSession.openForRead(openRequest); } } }
What I'm doing is to request the permission as soon as the session is open - but at this point the code is already starting a Graph API request, thus the permission request comes to late ...
Can't you request a permission at the same time you initialize the session?
To use the Facebook SDK in an Android Studio project, add the SDK as a build dependency and import the SDK. Go to Android Studio | New Project | Minimum SDK. Select API 15: Android 4.0. 3 (IceCreamSandwich) or higher and create your new project.
The Facebook SDK for Android gives you access to the following features: Facebook Login — A secure and convenient way for people to log into your app or website by using their Facebook credentials. Sharing — Enable people to post to Facebook from your app. People can share, send a message, and share to stories.
Login into Facebook and navigate to https://developers.facebook.com/apps/ Select the App you want to upgrade (you might have access to multiple apps) Click Settings > Advanced. Select the latest version under the Upgrade API Version section for both “Upgrade All Calls” and “Upgrade Calls for App Roles”
I was able to get it to work. It's a modification of your Version 2 sample. The link Jesse provided also helped a ton.
Here is the code I run through when authenticating a user:
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); } }else { Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() { @Override public void onCompleted(GraphUser user, Response response) { Log.w("myConsultant", user.getId() + " " + user.getName() + " " + user.getInnerJSONObject()); } }); } }
For testing I ran it through the below code after returning from Facebooks authentication:
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); if (mCurrentSession.isOpened()) { 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()); } }); } }
I solved the same problem by implementing my own Session.openActiveSession()
method:
private static Session openActiveSession(Activity activity, boolean allowLoginUI, StatusCallback callback, List<String> permissions) { OpenRequest openRequest = new OpenRequest(activity).setPermissions(permissions).setCallback(callback); Session session = new Builder(activity).build(); if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) { Session.setActiveSession(session); session.openForRead(openRequest); return session; } return null; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With