2013-06-09 15 views
10

Ich habe die folgende Aktivität und ich benutze Facebooks LoginButton. onSessionStateChange wird mehrmals aufgerufen. Ich habe eine asynctask, die ich nach einer erfolgreichen Anmeldung ausführen möchte, die auch eine neue Aktivität öffnet, sobald sie abgeschlossen ist. Im Moment startet dies mehrere asynchrone Aufgaben. Wie kann ich den Endzustand finden, sodass er nicht zweimal ausgelöst wird? Ich habe mir alle Beispiele angeschaut und Facebook sagt, dass session.isOpened() funktionieren sollte, aber es immer noch mehrere Male feuert.Facebook SDK 3.0 Rückruf wird zweimal ausgelöst

UPDATE:

Nach dem Session-Code aus onResume entfernt es wird nur einmal genannt, aber nach https://developers.facebook.com/docs/howtos/androidsdk/3.0/login-with-facebook/#step3 brauche ich diesen Code in onResume für bestimmte Situationen.

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

Ich denke, es ist zweimal aufgerufen, weil der Übergang vom geöffneten Zustand zum geöffneten. Versuchen Sie, den Status der Sitzung mit jedem Protokoll zu überprüfen, wenn Sie onSessionStateChange aufrufen. – 5agado

+0

@ 5agado Nur müde, und beide Male ist der Staat geöffnet. – nawlrus

+0

Wie Sie in der UPDATE-Phrase sagten, ist das Problem, dass zuerst die onCreate die Sitzung öffnen (verursacht den ersten Aufruf) als onResume den zweiten Aufruf verursachen, da eine geöffnete Sitzung gefunden wird. Sie können dem Facebook-Hinweis nicht folgen, oder Sie müssen etwas mehr prüfen, um die verschiedenen Fälle zu unterscheiden. – 5agado

Antwort

23

Ich hatte das gleiche Problem.

Ein Anruf kommt von UiLifecycleHelper, wenn es den Rückruf ruft:

UiLifecycleHelper callback 
onSessionStateChange() 

Die andere von Aktivität kommt die LoginFragment wieder aufzunehmen.

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

In vielen Fällen ist das in Ordnung, aber in Ihrem Fall ist es offensichtlich ein Problem aufgrund der AsyncTask.

Sie können die in onSessionStateChange() empfangene Sitzung zwischenspeichern und prüfen, ob ihr Status und tokenInfo geändert wurde, und erst dann Ihre asynchrone Aufgabe aufrufen. Die Überprüfung der Kombination aus Sitzungsstatus und tokenInfo sollte ausreichen:

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