¿Cómo cerrar sesión mediante programación en Facebook SDK 3.0 sin usar el botón de inicio / cierre de sesión de Facebook?

80

El título lo dice todo. Estoy usando un botón personalizado para obtener la información de Facebook del usuario (con el propósito de "registrarse"). Sin embargo, no quiero que la aplicación recuerde al último usuario registrado, ni al que está conectado actualmente en persona a través de la aplicación nativa de Facebook. Quiero que la actividad de inicio de sesión de Facebook aparezca cada vez. Es por eso que quiero cerrar la sesión de los usuarios anteriores mediante programación.

¿Cómo puedo hacer eso? Así es como hago el inicio de sesión:

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

Idealmente, haría una llamada al comienzo de este método para cerrar la sesión de cualquier usuario anterior.

Michael Eilers Smith
fuente

Respuestas:

161

Actualización para el último SDK:

Ahora la respuesta de @zeuter es correcta para Facebook SDK v4.7 +:

LoginManager.getInstance().logOut();

Respuesta original:

No utilice SessionTracker. Es una clase interna (paquete privado) y no está destinada a ser consumida como parte de la API pública. Como tal, su API puede cambiar en cualquier momento sin garantías de compatibilidad con versiones anteriores. Debería poder deshacerse de todas las instancias de SessionTracker en su código y simplemente usar la sesión activa en su lugar.

Para responder a su pregunta, si no desea conservar ningún dato de sesión, simplemente llame a closeAndClearTokenInformation cuando se cierre la aplicación.

Ming Li
fuente
3
Simplemente llame a Session.getActiveSession, y si devuelve nulo, entonces puede 1.) crear una nueva sesión usando Session.Builder y llamar a Session.setActiveSession, o 2.) llamar a uno de los métodos Session.openActiveSession (el static unos, que abre y establece la sesión activa para usted).
Ming Li
24
Y el hecho de que tengas que abrir una sesión para cerrar la sesión muestra lo malo que es el diseño del SDK de Facebook ... En lugar de ofrecer una API pública simple con devoluciones de llamada estándar, tienes que implementar un mecanismo de mierda ... increíble.
Martin Marconcini
18
¡El SDK y la documentación de Facebook son patéticos!
Skynet
3
Los documentos oficiales de Facebook incluyen código en ejemplos que está desaprobado - Luego tenemos que referirnos a la buena pila antigua para no desaprobar la misma.
Skynet
1
En lugar de agregar comentarios que no contribuyan a la conversación, debe dar ejemplos específicos donde falta la documentación (relacionada con la pregunta / respuesta), o puede ir al final de una página de documentación en particular en el portal para desarrolladores y hacer clic en en el botón "No" para "¿Fue útil este documento?".
Ming Li
87

Este método le ayudará a cerrar sesión en Facebook mediante programación en 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
fuente
3
¡Era la única solución funcional, en caso de usar fragmentos en lugar de Actividades, para mí!
Roger Alien
¿Por qué tienes la parte else en el código? Si el usuario no ha iniciado sesión, ¿por qué debería volver a iniciar sesión y luego cerrar la sesión?
Vihaan Verma
1
obteniendo el error java.lang.NullPointerException: El argumento 'applicationId' no puede ser nulo
Krunal Shah
Creo que la forma adecuada de inicializar la sesión es new Session.Builder (context) .build ();
Hasan
¿Por qué la elseparte?
aandis
66

Desde el SDK de Android de Facebook v4.0 (consulte el registro de cambios ), debe ejecutar lo siguiente:

LoginManager.getInstance().logOut();
zeuter
fuente
7
Gracias, pero no veo que esto realmente despeje la sesión. LoginManager.logout () solo llama internamente a "AccessToken.setCurrentAccessToken (null); Profile.setCurrentProfile (null);". Veo que el usuario aún puede iniciar sesión sin tener que volver a ingresar sus credenciales la próxima vez que inicie la aplicación. ¿Cómo se fuerza al usuario a volver a ingresar sus credenciales?
swooby
Este método me ayudó. Después de llamarlo e intentar volver a iniciar sesión, apareció una pantalla de ingreso de credenciales, como se esperaba. Gracias una tonelada.
Zsolt Boldizsár
1
Como señaló @swooby, esta solución desafortunadamente no funciona en aplicaciones que usan facebook sdk v4.x Después de cerrar la sesión, AccessToken es [{token de AccessToken: ACCESS_TOKEN_REMOVED permisos: [public_profile]}] pero AccessToken.getCurrentAccessToken (). GetToken () devuelve un token válido cadena incluso si el usuario ya no está registrado o revocó la autorización de la aplicación.
Lisitso
@Lisitso ¿Conoce una solución para eso ahora?
Jaec
1
@Jaec Utilicé la solución proporcionada por "Aniket Thakur". Puedes encontrar aquí entre las otras resposiciones. ¡Salud!
Lisitso
27

Aquí hay un fragmento que me permitió cerrar sesión mediante programación en Facebook. Avísame si ves algo que pueda necesitar mejorar.

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
fuente
¿Qué es jpotter6 mApp?
Amitsharma
Una instancia de la clase Application que está disponible en cualquier aplicación de Android
Eenvincible
13

Desde el SDK de Android de Facebook v4.0, debe ejecutar lo siguiente:

LoginManager.getInstance().logOut();

Esto no es suficiente. Esto simplemente borrará el perfil y el token de acceso en caché para que AccessToken.getCurrentAccessToken()y Profile.getCurrentProfile()ahora se vuelva nulo.

Para cerrar la sesión por completo, debe revocar los permisos y luego llamar LoginManager.getInstance().logOut();. Para revocar el permiso, ejecute la siguiente API gráfica:

    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
fuente
2
Esta es la respuesta correcta a esta pregunta. LoginManager.getInstance().logOut();solo borra la caché local, mientras que la GraphRequestllamada revoca mediante programación el acceso a la aplicación desde la cuenta de Facebook del usuario. Ambos son necesarios. Ninguno de los dos es suficiente solo.
YS
¿Dónde tenemos que poner este código para borrar permisos? ¡El código no funciona en mi caso! ¿Puede proporcionar un fragmento de código completo, señor.?
Akshay Shinde
El código funciona, pero da una advertencia: a la solicitud sin token de acceso le falta el identificador de aplicación o el token de cliente. ¿Necesito agregar algo a "/ {user-id} / permissions /" en el código anterior?
zeeshan
@zeeshan reemplaza {user-id} conmigo
Amritpal singh
8

La clase de sesión se ha eliminado en SDK 4.0. La imagen de inicio de sesión se realiza a través de la clase LoginManager . Entonces:

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

Como dice la referencia Actualización a SDK 4.0 :

Sesión eliminada : las clases AccessToken, LoginManager y CallbackManager reemplazan y reemplazan la funcionalidad en la clase Session.

felipe
fuente
1
La respuesta de zeuter es más corta y señala la misma llamada api. ¿Por qué el duplicado?
rekire
3

Sí, como mencionó @luizfelippe, la clase Session se eliminó desde el SDK 4.0. Necesitamos usar LoginManager.

Acabo de buscar en la clase LoginButton para cerrar la sesión. Están haciendo este tipo de verificación. Se desconectan solo si accessToken no es nulo. Entonces, creo que es mejor tener esto también en nuestro código.

AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
    LoginManager.getInstance().logOut();
}
SureshCS50
fuente
La respuesta de zeuter es más corta y señala la misma llamada api. ¿Por qué el duplicado?
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
fuente
0

Facebook ofrece dos formas de iniciar y cerrar sesión desde una cuenta. Uno es usar LoginButton y el otro es usar LoginManager. LoginButton es solo un botón que, al hacer clic, se realiza el inicio de sesión. Por otro lado, LoginManager hace esto por sí solo. En su caso, ha utilizado LoginManager para cerrar sesión automáticamente.

LoginManager.getInstance().logout() Esto funciona para tí.

aravindkanna
fuente