39 votes

Android - Facebook SDK 3 - Comment se connecter de manière programmatique sans LoginButton ?

J'écris une application qui s'intègre au SDK de Facebook, pour partager un contenu (chaîne de caractères) comme un message sur le mur. Maintenant, j'ai fait fonctionner l'exemple HelloFacebookSample. Cependant, il utilise leur LoginButton pour connecter l'utilisateur.

Ce n'est pas ce que je veux. Tout ce que je veux faire, c'est cliquer sur mon bouton de partage dans la barre d'action et le partager sur Facebook. Je veux donc me connecter de manière programmatique, j'ai essayé d'émuler ce que fait le LoginButton mais sans succès jusqu'à présent. J'obtiens

12-06 15:34:33.180 : E/AndroidRuntime(19493) : java.lang.UnsupportedOperationException : Session : une tentative a été faite d'autoriser à nouveau une session dont la demande est en attente.

public class MainActivity extends FacebookActivity {

@SuppressWarnings("serial")
private static final List<String> PERMISSIONS = new ArrayList<String>() {
    {
        add("publish_actions");
    }
};
private final int REAUTHORIZE_ACTIVITY = 3;
private Button postStatusUpdateButton;
private PendingAction pendingAction = PendingAction.NONE;

private enum PendingAction {
    NONE, POST_PHOTO, POST_STATUS_UPDATE
}

/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    postStatusUpdateButton = (Button) findViewById(R.id.postStatusUpdateButton);
    postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Log.d("MainActivity", "onClick");
            onClickPostStatusUpdate();
        }

    });

}

@Override
protected void onSessionStateChange(SessionState state, Exception exception) {
    super.onSessionStateChange(state, exception);
}

private interface GraphObjectWithId extends GraphObject {
    String getId();
}

private void showPublishResult(String message, GraphObject result, FacebookRequestError error) {
    String title = null;
    String alertMessage = null;
    if (error == null) {
        title = getString(R.string.success);
        String id = result.cast(GraphObjectWithId.class).getId();
        alertMessage = getString(R.string.successfully_posted_post, message, id);
    } else {
        title = getString(R.string.error);
        alertMessage = error.getErrorMessage();
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title).setMessage(alertMessage).setPositiveButton(getString(R.string.ok), null);
    builder.show();
}

private void onClickPostStatusUpdate() {
    Log.d("MainActivity", "onClickPostStatusUpdate");
    performPublish(PendingAction.POST_STATUS_UPDATE);
}

private boolean hasPublishPermission() {
    Session session = Session.getActiveSession();
    return session != null && session.getPermissions().contains("publish_actions");
}

private void performPublish(PendingAction action) {
    Log.d("MainActivity", "peformPublish");

    Session session = Session.getActiveSession();

    if (session == null) {
        session = new Session.Builder(this).setApplicationId("xxx").build();
        Session.setActiveSession(session);
    }

    if (!session.isOpened()) {
        Session.OpenRequest openRequest = new Session.OpenRequest(this);
        openRequest.setPermissions(PERMISSIONS);
        openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
        session.openForPublish(openRequest);
    }

    if (session != null) {
        // postStatusUpdate();
        pendingAction = action;
        if (hasPublishPermission()) {
            // We can do the action right away.
            handlePendingAction();
            // postStatusUpdate();
        } else {
            // We need to reauthorize, then complete the action when we get
            // called back.
            Session.ReauthorizeRequest reauthRequest = new Session.ReauthorizeRequest(this, PERMISSIONS)
                    .setRequestCode(REAUTHORIZE_ACTIVITY).setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
            session.reauthorizeForPublish(reauthRequest);
        }
    }
}

@SuppressWarnings("incomplete-switch")
private void handlePendingAction() {
    PendingAction previouslyPendingAction = pendingAction;
    // These actions may re-set pendingAction if they are still pending, but
    // we assume they
    // will succeed.
    pendingAction = PendingAction.NONE;

    switch (previouslyPendingAction) {
    case POST_STATUS_UPDATE:
        postStatusUpdate();
        break;
    }
}

private void postStatusUpdate() {
    // if (user != null && hasPublishPermission()) {
    if (hasPublishPermission()) {
        // final String message = getString(R.string.status_update,
        // user.getFirstName(), (new Date().toString()));
        final String message = "kks uz nemam nervy";
        Request request = Request.newStatusUpdateRequest(Session.getActiveSession(), message,
                new Request.Callback() {
                    @Override
                    public void onCompleted(Response response) {
                        showPublishResult(message, response.getGraphObject(), response.getError());
                    }
                });
        Request.executeBatchAsync(request);
    } else {
        pendingAction = PendingAction.POST_STATUS_UPDATE;
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("MainActivity", "onActivityResult");
    Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}

}

Bon, il s'agit toujours du projet HelloFacebookSample que j'essaie de plier dans le bon sens. La seule chose avec laquelle j'ai joué est la méthode performPublish, des trucs avec la création de la session.

J'espère qu'il existe un moyen plus facile ! P.S. : J'utilise Facebook SDK 3

1 votes

J'ai le même problème, comment l'avez-vous résolu ?

0 votes

Notez que dans les versions récentes du SDK Session.ReauthorizeRequest n'existe plus. Vous pouvez trouver un exemple fonctionnel mis à jour basé sur ce code aquí

21voto

Ming Li Points 8486

Est-ce que ce que tu as posté est toute ton activité ?

Vous devez également surcharger onActivityResult, et passer les valeurs à Session.getActiveSession().onActivityResult(...). Sinon, la session ne saura pas que l'utilisateur a autorisé votre application, et c'est pourquoi vous voyez l'erreur (la session pense qu'il y a toujours une demande d'authentification en attente, c'est pourquoi vous ne pouvez pas réautoriser la publication).

0 votes

J'ai posté le code source complet, mais le code dans performPublish est juste modifié, je n'ai aucune idée de ce que je fais vraiment...exposer appId etc...(il n'y a pas un moyen normal de se connecter par programme ?) ...peut-être que je devrais prendre un peu de recul, comment puis-je seulement me connecter par programme, sans poster une mise à jour du statut ?

0 votes

Ah, le problème dans votre code est que dans votre méthode performPublish, vous ouvrez la session, puis effectuez immédiatement une réautorisation en même temps. Si vous ajoutez un return ; après votre appel session.openForPublish, cela devrait régler le problème. Vous pouvez également consulter l'exemple FriendPickerSample (dans l'activité FriendPickerSampleActivity) pour voir comment ouvrir une session sans appuyer sur un bouton ni utiliser d'interface utilisateur.

0 votes

Merci pour votre aide, je vais regarder plus tard parce que j'ai mis en œuvre le sdk 2.0 pour l'instant comme je vais à la production bientôt et 3.0 est encore bêta de toute façon. (bien que j'ai implémenté la 2.0 en une heure d'étude et beaucoup moins de code ... o well)

18voto

sromku Points 2603

Comme j'ai eu le même sentiment que beaucoup de ceux qui ont upvoted le commentaire de @Beppi à la réponse de @Ming Li, et comme j'utilise Facebook SDK dans mes applications, j'ai décidé de créer un niveau d'API plus simplifié qui est basé sur le dernier Facebook SDK 3.0.b.

La bibliothèque open source : Android-simple-facebook
https://github.com/sromku/Android-simple-facebook

A votre question : How to login programatically?

  1. Définir l'écouteur de connexion/déconnexion

    // set login / logout listener
    OnLoginOutListener onLoginOutListener = new SimpleFacebook.OnLoginOutListener()
    {
    
        @Override
        public void onFail()
        {
            Log.w(TAG, "Failed to login");
        }
    
        @Override
        public void onException(Throwable throwable)
        {
            Log.e(TAG, "Bad thing happened", throwable);
        }
    
        @Override
        public void onThinking()
        {
            // show progress bar or something to the user while login is happening
            Log.i(TAG, "In progress");
        }
    
        @Override
        public void onLogout()
        {
            // change the state of the button or do whatever you want
            Log.i(TAG, "Logged out");
        }
    
        @Override
        public void onLogin()
        {
            // change the state of the button or do whatever you want
            Log.i(TAG, "Logged in");
        }
    };
    
    // set the listener
    mSimpleFacebook.setLogInOutListener(onLoginOutListener);
  2. En cliquant sur n'importe quelle vue, il suffit d'appeler login(Activity) méthode

    mSimpleFacebook.login(MainActivity.this);
  3. Pour se déconnecter de l'appel logout() méthode. Comme ceci :

    mSimpleFacebook.logout();

Comment régler permissions avant de se connecter, voir une explication très conviviale aquí .

J'espère que cela pourra être utile à quelqu'un :)

2 votes

Une bibliothèque très utile ! Elle m'a fait gagner de nombreuses heures. Merci de l'avoir mise à disposition.

4 votes

Merci. Le SDK de Facebook était/est et sera toujours terriblement mauvais. Je n'ai aucune idée de ce que l'architecte avait en tête lorsqu'il a conçu l'API, mais il avait clairement une vision très étrange. Le résultat est un grand nombre d'applications Android merdiques qui échouent constamment (et de manière aléatoire) ou qui envoient des messages cryptiques.

0 votes

C'est bien ! J'aimerais juste qu'il prenne en charge la publication via l'API graphique.

1voto

Benjamin Piette Points 410

Superbe morceau de code, merci.

Veuillez noter qu'avec la version v3 du SDK, le code reauthorize doit être remplacé par :

Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(FacebookActivity.this, PERMISSIONS)
                                .setRequestCode(REAUTHORIZE_ACTIVITY)
                                .setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
                        session.requestNewPublishPermissions(reauthRequest);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X