web-dev-qa-db-fra.com

StatusCallback non appelé après requestNewReadPermissions then requestNewPublishPermissions

Je développe une application Android qui s'intègre à Facebook. J'aimerais:

  1. Laisser l'utilisateur se connecter avec Facebook
  2. Obtenir l'adresse de messagerie de l'utilisateur sur Facebook (il peut s'agir d'une adresse de messagerie proxy , ce qui est correct)
  3. Publier sur le mur/la timeline de l'utilisateur en son nom

Techniquement, ce serait:

  1. Authentifier l'utilisateur
  2. Demander l'autorisation email)
  3. Demander la publish_stream permission } _

1. Authentifier l'utilisateur

J'ai appelé Session.openActiveSession() avec un Session.StatusCallback (j'ai déjà vérifié qu'il n'y avait aucune session ouverte active auparavant):

final Session.StatusCallback sessionStatusCallback = new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }

        // If session is just opened...
        if(state == SessionState.OPENED)
        {
            // Handle success case here.
            return;
        }
    };
};

// Start Facebook Login.
Session.openActiveSession(activity, true, sessionStatusCallback);

Mon rappel est appelé après une connexion réussie. Jusqu'ici tout va bien.

2. Demander l'autorisation email } _

Ceci est mon rappel de statut:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }

        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

Je demande l'autorisation avec Session.requestNewReadPermissions() :

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_READ = {"email"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_READ);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewReadPermissions(new Session.NewPermissionsRequest(activity, permissionList));

Mon rappel est appelé après autorisation. Jusqu'ici tout va bien.

3. Demander l'autorisation publish_stream)

Ceci est mon rappel de statut:

new Session.StatusCallback() {
    public void call(final Session session, SessionState state, Exception exception) {
        // If there is an exception...
        if(exception != null)
        {
            // Handle fail case here.
            return;
        }

        // If token is just updated...
        if(state == SessionState.OPENED_TOKEN_UPDATED)
        {
            // Handle success case here.
            return;
        }
    };
};

Je demande l'autorisation avec Session.requestNewPublishPermissions() :

final Session session = Session.getActiveSession();
final static String[] PERMISSION_ARRAY_PUBLISH = {"publish_stream"};
final List<String> permissionList = Arrays.asList(PERMISSION_ARRAY_PUBLISH);

// If all required permissions are available...
if(session.getPermissions().containsAll(permissionList))
{
    // Handle success case here.
    return;
}

// Request permissions.
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(activity, permissionList));

Cette fois-ci, mon rappel est not appelé après autorisation.

Enquête

Après une enquête plus poussée, j'ai trouvé que mon rappel était déclenché par com.facebook.Session#postStateChange(SessionState, SessionState, Exception) :

void postStateChange(final SessionState oldState, final SessionState newState, final Exception exception) {
    if (oldState == newState && exception == null) {
        return;
    }

    /* ... */
}

Puisque oldState et newState sont égaux (tous deux étant SessionState.OPENED_TOKEN_UPDATED _, mon rappel n'est pas appelé.

Question

Comment puis-je recevoir une notification après la permission est accordée pour la deuxième fois? Suis-je censé (close() } _ la session et rouvrir le cache ?

Information additionnelle

Mon Facebook SDK 3.0 Android est téléchargé à partir de ici , comme indiqué dans le Premiers pas avec le SDK de Facebook pour Android de Facebook.

22
Pang

C'est un bug.

[edit: Comme Guy le fait remarquer dans les commentaires, cela a été corrigé dans la version 3.0.1, cette solution de contournement n'est plus nécessaire]

La solution de contournement que vous avez mentionnée est fondamentalement correcte, bien que vous n’ayez pas besoin d’appeler de près. Si vous utilisez la seule session active, avant d'appeler requestNewPublishPermissions (), appelez simplement:

Session.openActiveSessionFromCache(myContext);

Si vous utilisez plusieurs sessions, vous devez initialiser une nouvelle session avec TokenCachingStrategy, vérifier qu'elle est dans l'état CREATED_TOKEN_LOADED et appeler openForRead (null);

Après avoir effectué l'une de ces tâches, requestNewPublishPermissions () devrait appeler votre notification une fois qu'elle est terminée.

10
rightparen

Code de travail basé sur rightparen's answer

Avant de demander la permission pour la deuxième fois (c'est-à-dire avant Session.requestNewPublishPermissions() ), procédez comme suit:

// Re-initialize Facebook session.
session.removeCallback(sessionStatusCallback);          // Remove callback from old session.
session = Session.openActiveSessionFromCache(context);  // Create new session by re-opening from cache.
session.addCallback(sessionStatusCallback);             // Add callback to new session.

Le code est toujours basé sur Facebook Android SDK 3.0, comme dans la question.

2
Pang

Un autre problème que j'ai rencontré est que mon requestCode pour la NewPermissionRequest n'était pas défini sur le même requestCode que j'avais l'habitude d'ouvrir ma Session pour la lecture avec, ainsi mon Session.StatusCallback n'a jamais été appelé lorsque les nouvelles autorisations ont été accordées.

Par exemple, dans ma onActivityResult, j'ai un chèque pour le requestCode et je délègue l'appel en conséquence, car d'autres éléments entrent dans cette méthode.

public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
    if (requestCode == FACEBOOK_AUTH_RESULT_CODE) {
        Session session = Session.getActiveSession();
        if(session != null) {
            session.onActivityResult(activity, requestCode, resultCode, data);
        }
    }       
}

J'ai ensuite ouvert ma Session avec le code suivant:

        Session.getActiveSession().openForRead(
            new Session.OpenRequest(activity).
                setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK).
                setRequestCode(FACEBOOK_AUTH_RESULT_CODE).
                setPermissions(MY_READ_PERMISSIONS));

J'ai ensuite oublié d'utiliser le même requestCode lors de la construction de ma NewPermissionRequest.

Voici à quoi la NewPermissionRequest correcte doit ressembler:

        Session.getActiveSession().requestNewPublishPermissions(
            new NewPermissionsRequest(activity, MY_PUBLISH_PERMISSIONS)
                .setRequestCode(FACEBOOK_AUTH_RESULT_CODE));
0
Akos Cz