Обратный вызов Facebook SDK 3.0 срабатывает дважды
У меня есть следующее действие, и я использую Facebook LoginButton. onSessionStateChange вызывается несколько раз. У меня есть asynctask, которую я хочу запустить после успешного входа в систему, который также открывает новую активность после завершения. Сейчас это запускает несколько асинхронных задач. Как я могу найти последнее состояние, чтобы он не срабатывал дважды? Ive просмотрел все примеры, и Facebook говорит, что session.isOpened() должен работать, но он все еще срабатывает несколько раз.
UPDATE:
После удаления кода сеанса из onResume он получает только один раз, но согласно https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/#step3 Мне нужен этот код в OnResume для определенных ситуаций.
public class LoginActivity extends SherlockActivity {
private static final String TAG = "LoginActivity";
private Context context;
private int statusCode;
private String emailAddress = null;
private String password = null;
private GraphUser fbUser;
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,
Exception exception) {
onSessionStateChange(session, state, exception);
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
context = getApplicationContext();
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
final LoginButton fbBtn = (LoginButton) findViewById(R.id.facebook_login);
fbBtn.setReadPermissions(Arrays.asList("basic_info", "email"));
/*
* fbBtn.setOnClickListener(new View.OnClickListener() {
*
* @Override public void onClick(View v) {
*
* Intent intent = new Intent(context, MainActivity.class);
* startActivity(intent);
*
* finish();
*
* } });
*/
}
@Override
protected void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
// For scenarios where the main activity is launched and user
// session is not null, the session state change notification
// may not be triggered. Trigger it if it open/closed.
Session session = Session.getActiveSession();
if (session != null && (session.isOpened() || session.isClosed())) {
onSessionStateChange(session, session.getState(), null);
}
uiHelper.onResume();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("FbLogin", "Result Code is - " + resultCode +"");
uiHelper.onActivityResult(requestCode, resultCode, data);
}
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
if (session != null && session.isOpened()) {
Log.i(TAG, "Logged in...");
Log.i(TAG, "Access Token" + session.getAccessToken());
if (state == SessionState.OPENED) {
Request.executeMeRequestAsync(session,
new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user,
Response response) {
if (user != null) {
Log.i(TAG, "User ID " + user.getId());
Log.i(TAG, "Email " + user.asMap().get("email"));
fbUser = user;
//FbRegisterTask fbReg = new FbRegisterTask(LoginActivity.this, user);
//fbReg.execute();
//finish();
}
}
});
}
} else if (session.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
}
Ответы
Ответ 1
У меня была такая же проблема.
Один вызов происходит из UiLifecycleHelper, когда он вызывает обратный вызов:
UiLifecycleHelper callback
onSessionStateChange()
Другое происходит из Activity, возобновляющего LoginFragment.
LoginActivity.onResumeFragments()
LoginFragment.onResume()
onSessionStateChange()
Во многих случаях это нормально, но в вашем случае это явно проблема из-за AsyncTask.
Вы можете кэшировать сеанс, полученный в onSessionStateChange(), и посмотреть, изменилось ли его состояние и токенInfo, и только затем вызвать вашу задачу async. Необходимо проверить комбинацию состояния сеанса и tokenInfo:
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
if (mSession == null || isSessionChanged(session)) {
mSession = session;
LogUtils.LOGFB(TAG, "Logged in using facebook");
LogUtils.LOGFB(TAG, "Access Token: " + session.getAccessToken());
// Run your AsyncTask
}
} else if (state.isClosed()) {
LogUtils.LOGFB(TAG, "Logged out from facebook");
// Display your non-authenticated UI
}
}
private boolean isSessionChanged(Session session) {
// Check if session state changed
if (mSession.getState() != session.getState())
return true;
// Check if accessToken changed
if (mSession.getAccessToken() != null) {
if (!mSession.getAccessToken().equals(session.getAccessToken()))
return true;
}
else if (session.getAccessToken() != null) {
return true;
}
// Nothing changed
return false;
}