39

我正在编写一个与 Facebook SDK 集成的应用程序,以分享一些(字符串)内容作为墙贴。现在,我让 HelloFacebookSample 工作了。但是它使用他们的 LoginButton 来登录用户。

我不想要那个。我要做的就是单击操作栏中的共享按钮并将其共享到 Facebook。因此我想以编程方式登录,我试图模拟 LoginButton 的作用,但到目前为止没有成功。我明白了

12-06 15:34:33.180:E/AndroidRuntime(19493):java.lang.UnsupportedOperationException:会话:尝试重新授权具有待处理请求的会话。

公共类 MainActivity 扩展 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);
}

}

好吧,这仍然是我试图以正确方式弯曲的 HelloFacebookSample 项目。我唯一玩过的是 performPublish 方法,用于创建会话。

希望有更简单的方法!PS:我正在使用 Facebook SDK 3

4

3 回答 3

21

你发布的是你的整个活动吗?

您还需要覆盖 onActivityResult,并将值传递给 Session.getActiveSession().onActivityResult(...)。否则,Session 将不知道用户已授权您的应用,这就是您看到错误的原因(Session 认为仍有待处理的身份验证请求,这就是您无法重新授权发布的原因)。

于 2012-12-06T18:13:11.950 回答
18

因为我和这里的许多人有同样的感觉,他们赞成@Beppi 对@Ming Li 的评论,而且由于我在我的应用程序中使用 Facebook SDK,我决定创建基于最新 Facebook SDK 3.0.b 的更简化的 API 级别。

开源库:android-simple-facebook
https://github.com/sromku/android-simple-facebook

对于你的问题:How to login programatically?

  1. 设置登录/注销监听器

    // 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. 单击任何视图,只需调用login(Activity)方法

    mSimpleFacebook.login(MainActivity.this);
    


  3. 注销调用logout()方法。像这样:

    mSimpleFacebook.logout();
    

如何在登录前设置权限,请看这里非常友好的解释。

希望它对某人有帮助:)

于 2013-08-09T11:26:32.147 回答
1

很棒的代码,谢谢。

请注意,对于 v3 SDK 版本,重新授权代码必须替换为:

Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(FacebookActivity.this, PERMISSIONS)
                                .setRequestCode(REAUTHORIZE_ACTIVITY)
                                .setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
                        session.requestNewPublishPermissions(reauthRequest);
于 2013-10-31T16:01:20.407 回答