2013-06-09 2 views
10

У меня есть следующая деятельность, и я использую LoginButton для входа в Facebook. onSessionStateChange вызывается несколько раз. У меня есть asynctask, которую я хочу запустить после успешного входа в систему, который также открывает новую активность после завершения. Сейчас это запускает несколько асинхронных задач. Как я могу найти последнее состояние, чтобы он не срабатывал дважды? Ive просмотрел все примеры, и Facebook говорит, что session.isOpened() должен работать, но он все еще срабатывает несколько раз.Facebook обратный вызов SDK 3.0 дважды

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's 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..."); 
    } 
} 
} 
+0

Я думаю, что это называется дважды, потому что переход от состояния открытия к открытому. Попробуйте проверить состояние сеанса с некоторым журналом каждый раз, когда вы вызываете onSessionStateChange. – 5agado

+0

@ 5agado Просто устал, и оба раза государство ОТКРЫТО. – nawlrus

+0

Как вы сказали в фразу UPDATE, проблема в том, что сначала onCreate открывает сеанс (вызывает первый вызов), чем onResume вызывает второй вызов, потому что находит открытый сеанс. Вы не можете следовать советам Facebook или вам нужно сделать еще несколько проверок, чтобы различать разные случаи. – 5agado

ответ

23

У меня была та же проблема.

Один звонок поступает из UiLifecycleHelper, когда он вызывает функцию обратного вызова:

UiLifecycleHelper callback 
onSessionStateChange() 

Другие происходит от деятельности возобновления в LoginFragment.

LoginActivity.onResumeFragments() 
LoginFragment.onResume() 
onSessionStateChange() 

Во многих случаях это нормально, но в вашем случае это, очевидно, проблема из-за AsyncTask.

Вы можете кэшировать сеанс, полученный в onSessionStateChange(), и посмотреть, изменилось ли его состояние и токенInfo, и только затем вызвать вашу задачу async. Необходимо проверить комбинацию состояния сеанса и токенаInfo:

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; 
} 
Смежные вопросы