我在我的 Android 应用程序中实现了 Facebook SDK。我正在使用 SDK 的登录功能。我想做的是以下几点:
- MainActivity 启动时,检查是否有活动会话
- 如果没有,让用户有机会登录 facebook
- 如果有,则必须将用户重定向到另一个 Activity(我们称之为:HomeActivity)。
当我的应用程序启动时,它会启动 MainActivity。我的onCreate()
方法如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.app = (ApplicationClass)getApplicationContext();
app.setUiHelper(new UiLifecycleHelper(this, callback));
uiHelper = app.getUiHelper();
uiHelper.onCreate(savedInstanceState);
if(this.app.getLoggedIn()) {
setContentView(R.layout.login);
startLoggingIn(); // <-- Makes login button invisible and starts spinner
login();
} else {
setContentView(R.layout.login);
}
}
ApplicationClass
是一个类,我在其中设置了可以在整个应用程序生命周期中使用的所有类型的信息。这并不重要,但我认为我将它包含在示例中。
所以当 MainActivity 启动时,它应该调用login()
方法,如下所示:
public void login() {
logging_in = true;
Log.i(TAG, "Loggin in");
synchronized (this) {
// start Facebook Login
Session.openActiveSession(this, true, new Session.StatusCallback() {
// callback when session changes state
@Override
public void call(Session session, SessionState state, Exception exception) {
if (Session.getActiveSession().isOpened()) {
// make request to the /me API
Request.executeMeRequestAsync(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
@Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) { // User is logged in
app.setUser(user);
app.setLoggedIn(true);
// Redirect user to the HomeActivity
Intent intent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(intent);
}
}
});
}
}
});
logging_in = false;
}
}
最后,我对 Facebook 会话的回调如下所示:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
synchronized (this) {
if( ! logging_in ) {
login();
}
}
} else if (state.isClosed()) {
setContentView(R.layout.login);
}
}
它做得很好,除了该login()
方法被调用了很多次。我的日志中的输出是:
为什么它会被调用这么多次?它显然确保HomeActivity
多次启动意图。我不知道为什么。
解决方案
稍微改变了我的 Session.StateCallback。现在看起来像这样:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
if(state == SessionState.OPENED_TOKEN_UPDATED) {
Log.i(TAG, "OPENED_TOKEN_UPDATED");
login();
} else if (state == SessionState.OPENED) {
if(app.getUser() != null) {
// Redirect user to the HomeActivity
Intent intent = new Intent(getBaseContext(), HomeActivity.class);
startActivity(intent);
} else {
login();
}
}
} else if (state.isClosed()) {
if(state == SessionState.CLOSED_LOGIN_FAILED) {
Log.i(TAG, "CLOSED_LOGIN_FAILED");
setContentView(R.layout.login);
} else if(state == SessionState.CLOSED) {
Log.i(TAG, "CLOSED");
//setContentView(R.layout.login);
}
}
}