2013-06-09 7 views
10

Ho la seguente attività e sto utilizzando il pulsante Login di Facebook. onSessionStateChange viene chiamato più volte. Ho un asynctask che voglio eseguire dopo un login riuscito che apre una nuova attività una volta completata. In questo momento inizia più attività asincrone. Come posso trovare lo stato finale in modo che non si spari due volte? Ive ha esaminato tutti gli esempi e Facebook afferma che session.isOpened() dovrebbe funzionare, ma continua a sparare più volte.Il richiamo di Facebook SDK 3.0 si attiva due volte

UPDATE:

Dopo aver rimosso il codice di sessione da onResume solo viene chiamato una volta, ma in base alle https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/#step3 Ho bisogno che il codice in onResume per determinate situazioni.

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

Penso che sia chiamato due volte perché la transizione dallo stato di apertura a quello aperto. Prova a controllare lo stato della sessione con qualche registro ogni volta che chiami onSessionStateChange. – 5agado

+0

@ 5agado Appena stanco che ed entrambe le volte lo stato è APERTO. – nawlrus

+0

Come hai detto nella frase UPDATE, il problema è che prima onCreate apre la sessione (causando la prima chiamata) che onResume causa la seconda chiamata perché trova una sessione aperta. Non puoi seguire il consiglio di Facebook o devi fare un altro controllo per differenziare i diversi casi. – 5agado

risposta

23

Ho avuto lo stesso problema.

Una chiamata è venuta da UiLifecycleHelper quando si richiama il callback:

UiLifecycleHelper callback 
onSessionStateChange() 

L'altro proviene da attività di riprendere la LoginFragment.

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

In molti casi, questo va bene, ma nel tuo caso è ovviamente un problema dovuto al AsyncTask.

È possibile memorizzare nella cache la sessione ricevuta in onSessionStateChange() e verificare se il suo stato e il tokenInfo sono stati modificati e solo successivamente richiamare l'attività asincrona. Il controllo della combinazione di sessione e tokenInfo dovrebbe essere sufficiente:

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