web-dev-qa-db-fra.com

Android - Facebook SDK 3 - Comment se connecter par programmation sans LoginButton

J'écris une application qui s'intègre au SDK Facebook, pour partager du contenu (chaîne) en tant que publication sur le mur. Maintenant, j'ai fait le travail HelloFacebookSample. Cependant, il utilise leur LoginButton pour connecter l'utilisateur.

Je n'en veux pas. Tout ce que je veux faire, c'est cliquer sur mon bouton de partage dans la barre d'actions et le partager sur Facebook. Par conséquent, je veux me connecter par programme, j'ai essayé d'émuler ce que fait le LoginButton mais sans succès jusqu'à présent. Je reçois

12-06 15: 34: 33.180: E/AndroidRuntime (19493): Java.lang.UnsupportedOperationException: Session: une tentative a été faite pour réautoriser une session qui a une demande en attente.

public class MainActivity étend 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);
}

}

Eh bien, c'est toujours le projet HelloFacebookSample que j'essaie de plier dans le bon sens. La seule chose avec laquelle j'ai joué est la méthode performPublish, avec la création de la session.

J'espère qu'il y a un moyen plus simple! P.S .: J'utilise Facebook SDK

39
urSus

Est-ce que vous avez posté l'intégralité de votre activité?

Vous devez également remplacer onActivityResult et transmettre 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).

21
Ming Li

Étant donné que j'avais le même sentiment que beaucoup ici qui ont voté pour le commentaire de @ Beppi à la réponse @Ming Li, et puisque j'utilise le SDK Facebook dans mes applications, j'ai décidé de créer un niveau d'API plus simplifié basé sur le dernier Facebook SDK 3.0.b.

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

À 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 la méthode login(Activity)

    mSimpleFacebook.login(MainActivity.this);
    


  3. Pour vous déconnecter, appelez la méthode logout(). Comme ça:

    mSimpleFacebook.logout();
    

Comment définir les autorisations avant la connexion, voir l'explication très conviviale ici .

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

18
sromku

Grand morceau de code, merci.

Veuillez noter qu'avec la version SDK v3, le code de réautorisation doit être remplacé par:

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