Avec le nouveau Android SDK 3.0 d'Android (sorti il y a quelques jours), le processus d'authentification a changé.
Alors, comment demandez-vous une autorisation de lecture telle que "friends_hometown"?
Le code suivant est la façon dont j'essaie de le faire - mais je suis sûr que ce n'est pas la façon dont vous devez le faire:
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);
}
}
}
Ce que je fais, c'est de demander l'autorisation dès que la session est ouverte - mais à ce stade, le code commence déjà une demande d'API Graph, donc la demande d'autorisation arrive en retard ...
Ne pouvez-vous pas demander une autorisation en même temps que vous initialisez la session?
Je vous recommande de lire notre tutoriel de connexion ici spécifiquement à l'étape 3. L'utilisation du bouton de connexion que nous fournissons est la méthode la plus pratique, (voir authButton.setReadPermissions()
)
MODIFIER:
Définir des autorisations sans utiliser le bouton de connexion est plus délicat car vous devrez faire toute la gestion de session à la main. En fouillant dans le code source du bouton de connexion, cette ligne de code est probablement ce dont vous avez besoin. Il semble que vous devrez créer votre propre Session.OpenRequest
Et définir ses attributs tels que les autorisations, le public et le comportement de connexion, puis récupérer la session en cours et appeler openForRead()
sur votre Session.OpenRequest
.
J'ai pu le faire fonctionner. Il s'agit d'une modification de votre exemple de version 2. Le lien fourni par Jesse a également aidé une tonne.
Voici le code que je parcours lors de l'authentification d'un utilisateur:
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());
}
});
}
}
Pour les tests, je l'ai exécuté à travers le code ci-dessous après être revenu de l'authentification Facebook:
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());
}
});
}
}
J'ai résolu le même problème en implémentant ma propre méthode Session.openActiveSession()
:
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;
}
Bien que la première question ait été posée il y a quelques mois et qu'il existe des réponses acceptées, il existe une autre solution plus élégante pour demander plus d'autorisations à l'utilisateur lors de l'authentification. De plus, Facebook SDK 3.5 a été publié récemment et il serait bon de rafraîchir ce fil :)
Ainsi, la solution élégante est livrée avec cette bibliothèque open source: Android-simple-facebook
Ajoutez simplement les lignes suivantes dans votre classe Activity
:
Définissez et sélectionnez les autorisations dont vous avez besoin, comme friends_hometown
:
Permissions[] permissions = new Permissions[]
{
Permissions.FRIENDS_HOMETOWN,
Permissions.FRIENDS_PHOTOS,
Permissions.PUBLISH_ACTION
};
La grande chose ici avec les autorisations, c'est que vous n'avez pas besoin de séparer les autorisations de lecture et de publication. Vous venez de mentionner ce dont vous avez besoin et la bibliothèque se chargera du reste.
Générez et définissez la configuration en mettant app_id
, namespace
et permissions
:
SimpleFacebookConfiguration configuration = new SimpleFacebookConfiguration.Builder()
.setAppId("625994234086470")
.setNamespace("sromkuapp")
.setPermissions(permissions)
.build();
Et, créez l'instance SimpleFacebook
et définissez cette configuration:
SimpleFacebook simpleFacebook = SimpleFacebook.getInstance(Activity);
simpleFacebook.setConfiguration(configuration);
Maintenant, vous pouvez exécuter les méthodes comme: connexion , publier le flux/l'histoire , inviter ,…
mSimpleFacebook.login(OnLoginListener);
mSimpleFacebook.logout(OnLogoutListener);
Pour plus d'exemples et d'utilisation, consultez cette page: https://github.com/sromku/Android-simple-facebook#actions-examples