2013-06-09 19 views
10

Mam następujące działanie i korzystam z przycisku logowania na Facebooku. Funkcja onSessionStateChange jest wywoływana wiele razy. Mam asynktask, który chcę uruchomić po udanym logowaniu, które również otwiera nowe działanie po zakończeniu. W tej chwili uruchamia wiele zadań asynchronicznych. Jak mogę znaleźć ostateczny stan, aby nie wystrzelił dwa razy? Przejrzałem wszystkie przykłady, a Facebook powiedział, że session.isOpened() powinno działać, ale wciąż jest uruchamiane wielokrotnie.Dwa wywołania zwrotne w programie Facebook SDK 3.0 dwa razy:

UPDATE:

Po usunięciu kod sesji z onResume tylko to jest wywoływana raz, ale według https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/#step3 muszę tego kodu w OnResume dla pewnych sytuacjach.

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

Myślę, że to się nazywa dwa razy, ponieważ przejście ze stanu otwarcia do stanu otwartego. Spróbuj sprawdzić stan sesji za pomocą niektórych dzienników za każdym razem, gdy wywoływana jest funkcja onSessionStateChange. – 5agado

+0

@ 5agado Po prostu zmęczony, że i za każdym razem stan jest OTWARTY. – nawlrus

+0

Tak jak powiedziałeś w wyrażeniu UPDATE, problem polega na tym, że najpierw onCreate otwiera sesję (powodując pierwsze wywołanie), niż onResume wywołuje drugie wywołanie, ponieważ znajduje otwartą sesję. Nie można postępować zgodnie z poradą na Facebooku lub trzeba jeszcze sprawdzić, aby rozróżnić różne przypadki. – 5agado

Odpowiedz

23

Miałem ten sam problem.

Jeden telefon pochodzi z UiLifecycleHelper gdy przywołuje zwrotnego:

UiLifecycleHelper callback 
onSessionStateChange() 

Drugi pochodzi z działalności wznawianie z LoginFragment.

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

W wielu przypadkach, to jest w porządku, ale w Twoim przypadku jest to oczywiście problem ze względu na AsyncTask.

Można buforować sesję odebraną w onSessionStateChange() i sprawdzić, czy zmienił się jej stan i tokenInfo, a dopiero potem wywołać zadanie asynchroniczne. Sprawdzanie kombinacji stanu sesji i tokenInfo powinno wystarczyć:

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; 
}