Jak programowo wylogować się z Facebook SDK 3.0 bez użycia przycisku logowania / wylogowania z Facebooka?

80

Tytuł mówi wszystko. Używam niestandardowego przycisku, aby pobrać informacje z Facebooka użytkownika (do celów „rejestracji”). Jednak nie chcę, aby aplikacja zapamiętała ostatnio zarejestrowanego użytkownika, ani aktualnie zalogowanego osobiście przez natywną aplikację Facebooka. Chcę, aby aktywność logowania na Facebooku pojawiała się za każdym razem. Dlatego chcę wylogować wszystkich poprzednich użytkowników programowo.

Jak mogę to zrobić? Tak się loguję:

private void signInWithFacebook() {

    SessionTracker sessionTracker = new SessionTracker(getBaseContext(), new StatusCallback() 
    {
        @Override
        public void call(Session session, SessionState state, Exception exception) { 
        }
    }, null, false);

    String applicationId = Utility.getMetadataApplicationId(getBaseContext());
    mCurrentSession = sessionTracker.getSession();

    if (mCurrentSession == null || mCurrentSession.getState().isClosed()) {
        sessionTracker.setSession(null);
        Session session = new Session.Builder(getBaseContext()).setApplicationId(applicationId).build();
        Session.setActiveSession(session);
        mCurrentSession = session;
    }

    if (!mCurrentSession.isOpened()) {
        Session.OpenRequest openRequest = null;
        openRequest = new Session.OpenRequest(RegisterActivity.this);

        if (openRequest != null) {
            openRequest.setPermissions(null);
            openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);

            mCurrentSession.openForRead(openRequest);
        }
    }else {
        Request.executeMeRequestAsync(mCurrentSession, new Request.GraphUserCallback() {
              @Override
              public void onCompleted(GraphUser user, Response response) {
                  fillProfileWithFacebook( user );
              }
            });
    }
}

Najlepiej byłoby, gdyby na początku tej metody zadzwonił, aby wylogować poprzednich użytkowników.

Michael Eilers Smith
źródło

Odpowiedzi:

161

Aktualizacja do najnowszego SDK:

Teraz odpowiedź @ zeuter jest poprawna dla Facebook SDK v4.7 +:

LoginManager.getInstance().logOut();

Oryginalna odpowiedź:

Nie używaj SessionTracker. Jest to klasa wewnętrzna (prywatna pakietu) i nie jest przeznaczona do używania jako część publicznego interfejsu API. W związku z tym jego interfejs API może ulec zmianie w dowolnym momencie bez żadnych gwarancji zgodności wstecznej. Powinieneś móc pozbyć się wszystkich wystąpień SessionTracker w swoim kodzie i zamiast tego po prostu użyć aktywnej sesji.

Aby odpowiedzieć na swoje pytanie, jeśli nie chcesz przechowywać żadnych danych sesji, po prostu wywołaj funkcję closeAndClearTokenInformation po zamknięciu aplikacji.

Ming Li
źródło
3
Po prostu wywołujesz Session.getActiveSession, a jeśli zwróci wartość null, możesz 1.) utworzyć nową sesję za pomocą Session.Builder i wywołać Session.setActiveSession lub 2.) wywołać jedną z metod Session.openActiveSession (statyczna te, które zarówno otwierają, jak i ustawiają aktywną sesję).
Ming Li
24
A fakt, że musisz otworzyć sesję, aby się wylogować, pokazuje, jak zły jest projekt Facebook SDK… Zamiast oferować proste publiczne API ze standardowymi wywołaniami zwrotnymi, musisz wdrożyć kiepski mechanizm… niesamowite.
Martin Marconcini
18
Facebook SDK i dokumentacja są żałosne!
Skynet
3
Oficjalne dokumenty Facebooka zawierają w przykładach kod, który jest przestarzały - Następnie musimy odwołać się do starego dobrego stosu, aby go cofnąć.
Skynet
1
Zamiast dodawać komentarze, które nie wnoszą wkładu w rozmowę, powinieneś podać konkretne przykłady, w których brakuje dokumentacji (dotyczące pytania / odpowiedzi) lub możesz przejść na dół konkretnej strony z dokumentacją w portalu deweloperskim i kliknąć na przycisku „Nie” dla pytania „Czy ten dokument był pomocny?”.
Ming Li
87

Ta metoda pomoże Ci wylogować się programowo z Facebooka w systemie Android

/**
 * Logout From Facebook 
 */
public static void callFacebookLogout(Context context) {
    Session session = Session.getActiveSession();
    if (session != null) {

        if (!session.isClosed()) {
            session.closeAndClearTokenInformation();
            //clear your preferences if saved
        }
    } else {

        session = new Session(context);
        Session.setActiveSession(session);

        session.closeAndClearTokenInformation();
            //clear your preferences if saved

    }

}
Rikin Prajapati
źródło
3
Było dla mnie jedynym działającym rozwiązaniem w przypadku użycia fragmentów zamiast Aktywności!
Roger Alien,
dlaczego masz w kodzie drugą część? Jeśli użytkownik nie jest zalogowany, dlaczego miałoby być wymagane ponowne zalogowanie się, a następnie wylogowanie?
Vihaan Verma
1
uzyskiwanie błędu java.lang.NullPointerException: Argument „applicationId” nie może mieć wartości null
Krunal Shah
Myślę, że odpowiednim sposobem na zainicjowanie sesji jest nowa Session.Builder (kontekst) .build ();
hasan
66

Ponieważ Facebook Android SDK v4.0 (patrz dziennik zmian ), musisz wykonać następujące czynności:

LoginManager.getInstance().logOut();
zeuter
źródło
7
Dzięki, ale nie widzę, żeby to faktycznie wyczyściło sesję. LoginManager.logout () wywołuje tylko wewnętrznie „AccessToken.setCurrentAccessToken (null); Profile.setCurrentProfile (null);”. Widzę, że użytkownik nadal może się zalogować bez konieczności ponownego wprowadzania danych logowania przy następnym uruchomieniu aplikacji. Jak zmusić użytkownika do ponownego wprowadzenia danych logowania?
swooby
Ta metoda mi pomogła. Po wywołaniu go i próbie ponownego zalogowania, zgodnie z oczekiwaniami, pojawił się ekran wprowadzania danych logowania. Dzięki za tonę.
Zsolt Boldizsár
1
Jak wskazał @swooby, to rozwiązanie niestety nie działa w aplikacjach korzystających z facebook sdk v4.x Po wykonaniu logOut AccessToken ma [{AccessToken token: ACCESS_TOKEN_REMOVED uprawnienia: [public_profile]}], ale AccessToken.getCurrentAccessToken (). GetToken () zwraca prawidłowy token string, nawet jeśli użytkownik nie jest już zalogowany lub odwołał autoryzację do aplikacji.
Lisitso
@Lisitso Czy znasz teraz rozwiązanie tego problemu?
Jaec,
1
@Jaec Skorzystałem z rozwiązania sprawdzonego przez „Aniket Thakur”. Możesz znaleźć tutaj między innymi respekt. Twoje zdrowie!
Lisitso
27

Oto fragment, który pozwolił mi programowo wylogować się z Facebooka. Daj mi znać, jeśli zobaczysz coś, co powinienem poprawić.

private void logout(){
    // clear any user information
    mApp.clearUserPrefs();
    // find the active session which can only be facebook in my app
    Session session = Session.getActiveSession();
    // run the closeAndClearTokenInformation which does the following
    // DOCS : Closes the local in-memory Session object and clears any persistent 
    // cache related to the Session.
    session.closeAndClearTokenInformation();
    // return the user to the login screen
    startActivity(new Intent(getApplicationContext(), LoginActivity.class));
    // make sure the user can not access the page after he/she is logged out
    // clear the activity stack
    finish();
}
jpotts18
źródło
co to jest jpotter6 mApp?
Amitsharma
Wystąpienie klasy Application, która jest dostępna w dowolnej aplikacji na Androida
Eenvincible
13

Ponieważ Facebook Android SDK v4.0, musisz wykonać następujące czynności:

LoginManager.getInstance().logOut();

To nie wystarczy. Spowoduje to po prostu wyczyszczenie przechowywanego w pamięci podręcznej tokenu dostępu i profilu, dzięki czemu AccessToken.getCurrentAccessToken()i Profile.getCurrentProfile()będzie teraz mieć wartość zerową.

Aby całkowicie się wylogować, musisz cofnąć uprawnienia, a następnie zadzwonić LoginManager.getInstance().logOut();. Aby cofnąć uprawnienia, wykonaj następujące Graph API -

    GraphRequest delPermRequest = new GraphRequest(AccessToken.getCurrentAccessToken(), "/{user-id}/permissions/", null, HttpMethod.DELETE, new GraphRequest.Callback() {
        @Override
        public void onCompleted(GraphResponse graphResponse) {
            if(graphResponse!=null){
                FacebookRequestError error =graphResponse.getError();
                if(error!=null){
                    Log.e(TAG, error.toString());
                }else {
                    finish();
                }
            }
        }
    });
    Log.d(TAG,"Executing revoke permissions with graph path" + delPermRequest.getGraphPath());
    delPermRequest.executeAsync();
Aniket Thakur
źródło
2
To jest prawidłowa odpowiedź na to pytanie. LoginManager.getInstance().logOut();czyści tylko lokalną pamięć podręczną, podczas gdy GraphRequestwywołanie programowo unieważnia dostęp do aplikacji z konta użytkownika na Facebooku. Oba są konieczne. Samo też nie wystarczy.
YS
Gdzie musimy umieścić ten kod dla uprawnień do usuwania ?! Kod nie działa w moim przypadku! Czy możesz podać pełny fragment kodu, sir.!?
Akshay Shinde
Kod działa, ale ostrzega: Żądanie bez tokena dostępu, brak identyfikatora aplikacji lub tokena klienta. Czy muszę coś dodać do „/ {user-id} / permissions /” w powyższym kodzie?
zeeshan
@zeeshan zastąp {user-id} mną
Amritpal singh
8

Klasa sesji została usunięta z pakietu SDK 4.0. Zarządzanie logowaniem odbywa się za pośrednictwem klasy LoginManager . Więc:

mLoginManager = LoginManager.getInstance();
mLoginManager.logOut();

Jak mówi odniesienie Upgrading to SDK 4.0 :

Sesja usunięta - klasy AccessToken, LoginManager i CallbackManager zastępują i zastępują funkcje w klasie Session.

felippe
źródło
1
Odpowiedź zeuter jest krótsza i wskazuje na to samo wywołanie interfejsu API. Dlaczego duplikat?
rekire
3

Tak, jak wspomniał @luizfelippe, klasa sesji została usunięta od SDK 4.0. Musimy użyć LoginManagera.

Właśnie zajrzałem do klasy LoginButton, aby się wylogować. Robią tego rodzaju czek. Wylogowuje się tylko wtedy, gdy accessToken nie jest null. Więc myślę, że lepiej mieć to również w naszym kodzie.

AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
    LoginManager.getInstance().logOut();
}
SureshCS50
źródło
Odpowiedź zeuter jest krótsza i wskazuje na to samo wywołanie interfejsu API. Dlaczego duplikat?
rekire
0
private Session.StatusCallback statusCallback = new SessionStatusCallback();

logout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Session.openActiveSession(this, true, statusCallback);  
}
});

private class SessionStatusCallback implements Session.StatusCallback {
@Override
public void call(Session session, SessionState state,
Exception exception) {
session.closeAndClearTokenInformation();    
}
}
selva_pollachi
źródło
0

Facebook zapewnia dwa sposoby logowania i wylogowywania się z konta. Jednym z nich jest użycie LoginButton, a drugim LoginManager. LoginButton to po prostu przycisk, którego kliknięcie oznacza zakończenie logowania. Z drugiej strony LoginManager robi to samodzielnie. W twoim przypadku musisz użyć LoginManager do automatycznego wylogowania.

LoginManager.getInstance().logout() czy to działa dla Ciebie.

aravindkanna
źródło