Wie kann ich mich programmgesteuert von Facebook SDK 3.0 abmelden, ohne die Facebook-Schaltfläche zum Anmelden / Abmelden zu verwenden?

80

Der Titel sagt alles. Ich verwende eine benutzerdefinierte Schaltfläche, um die Facebook-Informationen des Benutzers abzurufen (für "Anmeldezwecke"). Ich möchte jedoch nicht, dass sich die App an den zuletzt registrierten Benutzer erinnert, noch an die aktuell über die native Facebook-App angemeldete Person. Ich möchte, dass die Facebook-Anmeldeaktivität jedes Mal angezeigt wird. Aus diesem Grund möchte ich frühere Benutzer programmgesteuert abmelden.

Wie kann ich das machen? So mache ich das Login:

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

Idealerweise würde ich zu Beginn dieser Methode einen Aufruf tätigen, um frühere Benutzer abzumelden.

Michael Eilers Smith
quelle

Antworten:

161

Update für das neueste SDK:

Jetzt ist die Antwort von @ zeuter für Facebook SDK v4.7 + korrekt:

LoginManager.getInstance().logOut();

Ursprüngliche Antwort:

Bitte verwenden Sie nicht SessionTracker. Es ist eine interne (paketprivate) Klasse und darf nicht als Teil der öffentlichen API verwendet werden. Daher kann sich die API jederzeit ohne Abwärtskompatibilitätsgarantien ändern. Sie sollten in der Lage sein, alle Instanzen von SessionTracker in Ihrem Code zu entfernen und stattdessen nur die aktive Sitzung zu verwenden.

Um Ihre Frage zu beantworten, rufen Sie beim Schließen Ihrer App einfach closeAndClearTokenInformation auf , wenn Sie keine Sitzungsdaten behalten möchten .

Ming Li
quelle
3
Sie rufen einfach Session.getActiveSession auf, und wenn es null zurückgibt, können Sie entweder 1.) eine neue Sitzung mit Session.Builder erstellen und Session.setActiveSession aufrufen oder 2.) eine der Session.openActiveSession-Methoden (die statische) aufrufen diejenigen, die die aktive Sitzung für Sie öffnen und festlegen).
Ming Li
24
Und die Tatsache, dass Sie eine Sitzung öffnen müssen, um sich abzumelden, zeigt, wie schlecht das Facebook SDK-Design ist… Anstatt eine einfache öffentliche API mit Standard-Rückrufen anzubieten, müssen Sie einen beschissenen Mechanismus implementieren… erstaunlich.
Martin Marconcini
18
Facebook SDK und Dokumentation ist erbärmlich!
Skynet
3
Die offiziellen Facebook-Dokumente enthalten Code in Beispielen, der veraltet ist. Dann müssen wir auf den guten alten Stapel verweisen, um ihn nicht mehr zu veralten.
Skynet
1
Anstatt Kommentare hinzuzufügen, die nicht zur Konversation beitragen, sollten Sie bestimmte Beispiele angeben, bei denen die Dokumentation fehlt (in Bezug auf die Frage / Antwort), oder Sie können zum Ende einer bestimmten Dokumentationsseite im Entwicklerportal gehen und auf klicken auf der Schaltfläche "Nein" für "War dieses Dokument hilfreich?".
Ming Li
87

Diese Methode hilft Ihnen, sich programmgesteuert von Facebook in Android abzumelden

/**
 * 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
quelle
3
War für mich die einzige funktionierende Lösung, wenn Fragmente anstelle von Aktivitäten verwendet wurden!
Roger Alien
Warum hast du den else-Teil im Code? Wenn der Benutzer nicht angemeldet ist, warum muss er sich dann erneut anmelden und dann abmelden?
Vihaan Verma
1
Fehler erhalten java.lang.NullPointerException: Argument 'applicationId' kann nicht null sein
Krunal Shah
Ich denke, der geeignete Weg, um die Sitzung zu initialisieren, ist new Session.Builder (context) .build ();
Hasan
Warum das elseTeil?
Aandis
66

Seit dem Android SDK v4.0 von Facebook (siehe Änderungsprotokoll ) müssen Sie Folgendes ausführen:

LoginManager.getInstance().logOut();
Zeuter
quelle
6
Danke, aber ich sehe nicht, dass dies die Sitzung tatsächlich beendet. LoginManager.logout () ruft nur intern "AccessToken.setCurrentAccessToken (null); Profile.setCurrentProfile (null);" auf. Ich sehe, dass sich der Benutzer weiterhin anmelden kann, ohne beim nächsten Start der App die Anmeldeinformationen erneut eingeben zu müssen. Wie zwingen Sie den Benutzer, seine Anmeldeinformationen erneut einzugeben?
Swooby
Diese Methode hat mir geholfen. Nach dem Aufruf und dem Versuch, sich erneut anzumelden, wurde erwartungsgemäß ein Bildschirm mit den Anmeldeinformationen angezeigt. Danke vielmals.
Zsolt Boldizsár
1
Wie @swooby betonte, funktioniert diese Lösung leider nicht auf Apps, die Facebook sdk v4.x verwenden. Nach dem Erstellen von logOut ist AccessToken [{AccessToken-Token: ACCESS_TOKEN_REMOVED-Berechtigungen: [public_profile]}], aber AccessToken.getCurrentAccessToken (). GetToken () gibt ein gültiges Token zurück Zeichenfolge, auch wenn der Benutzer nicht mehr angemeldet ist oder die Autorisierung für die App widerrufen hat.
Lisitso
@Lisitso Kennen Sie jetzt eine Lösung dafür?
Jaec
1
@Jaec Ich habe die von "Aniket Thakur" bereitgestellte Lösung verwendet. Sie finden hier unter den anderen Antworten. Prost!
Lisitso
27

Hier ist ein Ausschnitt, mit dem ich mich programmgesteuert von Facebook abmelden konnte. Lassen Sie mich wissen, wenn Sie etwas sehen, das ich möglicherweise verbessern muss.

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
quelle
Was ist jpotter6 mApp?
Amitsharma
Eine Instanz der Anwendungsklasse, die in jeder Android-Anwendung verfügbar ist
Eenvincible
13

Seit dem Android SDK v4.0 von Facebook müssen Sie Folgendes ausführen:

LoginManager.getInstance().logOut();

Das reicht nicht aus. Dies wird einfach im Cache gespeicherten Zugriffstoken löschen und Profile , so dass AccessToken.getCurrentAccessToken()und Profile.getCurrentProfile()wird nun geworden null.

Um sich vollständig abzumelden, müssen Sie die Berechtigungen widerrufen und dann anrufen LoginManager.getInstance().logOut();. Um die Berechtigung zu widerrufen, führen Sie die folgende Diagramm-API aus:

    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
quelle
2
Dies ist die richtige Antwort auf diese Frage. LoginManager.getInstance().logOut();löscht nur den lokalen Cache, während der GraphRequestAnruf den App-Zugriff vom Facebook-Konto des Benutzers programmgesteuert widerruft. Beides ist notwendig. Weder ist genug allein.
YS
Wo müssen wir diesen Code für Löschberechtigungen ablegen?! Code funktioniert in meinem Fall nicht! Können Sie einen vollständigen Code-Ausschnitt bereitstellen, Sir.!?
Akshay Shinde
Der Code funktioniert, gibt jedoch eine Warnung aus: Anforderung ohne Zugriffstoken fehlende Anwendungs-ID oder Client-Token. Muss ich im obigen Code etwas zu "/ {Benutzer-ID} / Berechtigungen /" hinzufügen?
Zeeshan
@zeeshan ersetzen {Benutzer-ID} durch mich
Amritpal singh
8

Die Sitzungsklasse wurde in SDK 4.0 entfernt. Das Login-Management erfolgt über die Klasse LoginManager . So:

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

In der Referenz Upgrade auf SDK 4.0 heißt es:

Sitzung entfernt - AccessToken-, LoginManager- und CallbackManager-Klassen ersetzen und ersetzen die Funktionen in der Session-Klasse.

felippe
quelle
1
Die Antwort von Zeuter ist kürzer und weist auf den gleichen API-Aufruf hin. Warum das Duplikat?
rekire
3

Ja, wie @luizfelippe erwähnte, wurde die Sitzungsklasse seit SDK 4.0 entfernt. Wir müssen LoginManager verwenden.

Ich habe mir gerade die LoginButton- Klasse zum Abmelden angesehen. Sie machen diese Art von Scheck. Sie melden sich nur ab, wenn accessToken nicht null ist. Ich denke, es ist besser, dies auch in unserem Code zu haben.

AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
    LoginManager.getInstance().logOut();
}
SureshCS50
quelle
Die Antwort von Zeuter ist kürzer und weist auf den gleichen API-Aufruf hin. Warum das 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
quelle
0

Facebook bietet zwei Möglichkeiten, sich von einem Konto aus anzumelden und abzumelden. Eine ist die Verwendung von LoginButton und die andere die Verwendung von LoginManager. LoginButton ist nur eine Schaltfläche, mit der beim Anmelden die Anmeldung abgeschlossen wird. Auf der anderen Seite macht LoginManager dies alleine. In Ihrem Fall haben Sie LoginManager verwendet, um sich automatisch abzumelden.

LoginManager.getInstance().logout() Geht das für dich.

aravindkanna
quelle