如何以编程方式从Facebook SDK 3.0注销而不使用Facebook登录/注销按钮?


80

标题说明了一切。我正在使用自定义按钮来获取用户的Facebook信息(用于“注册”目的)。但是,我不希望该应用程序记住上次注册的用户,也不要记住当前通过Facebook本机应用程序登录的人。我希望Facebook登录活动每次都弹出。这就是为什么我要以编程方式注销以前的所有用户。

我怎样才能做到这一点?这是我进行登录的方式:

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

理想情况下,我将在此方法的开头进行调用以注销以前的所有用户。

Answers:


161

最新SDK的更新:

现在@zeuter的答案对于Facebook SDK v4.7 +是正确的:

LoginManager.getInstance().logOut();

原始答案:

请不要使用SessionTracker。它是一个内部(私有包)类,并不意味着要作为公共API的一部分使用。因此,其API可能随时更改,而没有任何向后兼容性的保证。您应该可以在代码中摆脱SessionTracker的所有实例,而只需使用活动会话即可。

要回答您的问题,如果您不想保留任何会话数据,只需在应用程序关闭时调用closeAndClearTokenInformation


3
您只需调用Session.getActiveSession,如果它返回null,则可以1.)使用Session.Builder创建一个新的Session,然后调用Session.setActiveSession,或2.)调用Session.openActiveSession方法之一(静态,同时打开并为您设置活动会话)。
Ming Li

24
而且,您必须打开会话以退出登录这一事实表明,Facebook SDK设计有多糟糕……除了提供带有标准回调的简单公共API之外,您还必须实现一种cr脚的机制……令人惊奇。
Martin Marconcini

18
Facebook SDK和文档太可悲了!
天网2015年

3
Facebook官方文档在示例中包含了不推荐使用的代码-然后,我们必须引用旧的堆栈以取消弃用相同的代码。
天网2015年

1
您应该提供缺少文档的特定示例(与问题/答案有关),而不是添加对对话无用的注释,或者可以转到开发人员门户上特定文档页面的底部,然后单击单击“否”按钮上的“此文档对您有帮助吗?”。
Ming Li

87

此方法将帮助您在Android中以编程方式从Facebook注销

/**
 * 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

    }

}

3
对于我来说,使用片段而不是活动是唯一可行的解​​决方案!
Roger Alien 2014年

为什么在代码中包含else部分?如果用户未登录,为什么需要再次登录然后注销?
Vihaan Verma 2014年

1
收到错误java.lang.NullPointerException:参数'applicationId'不能为null
Krunal Shah

我认为初始化会话的适当方法是new Session.Builder(context).build();
哈桑2015年

为什么要else零件?
aandis 2015年

66

从Facebook的Android SDK v4.0(请参阅changelog)开始,您需要执行以下操作:

LoginManager.getInstance().logOut();

7
谢谢,但是我看不到这实际上可以清除会话。LoginManager.logout()仅在内部调用“ AccessToken.setCurrentAccessToken(null); Profile.setCurrentProfile(null);”。我看到用户仍然可以登录,而无需在下次启动应用程序时重新输入凭据。您如何强制用户重新输入其凭据?
swooby

这种方法帮助了我。调用它并尝试重新登录后,按预期显示输入凭据屏幕。万分感谢。
ZsoltBoldizsár2015年

1
如@swooby所指出的,不幸的是,此解决方案不适用于使用facebook sdk v4.x的应用程序。注销后,AccessToken为[{AccessToken令牌:ACCESS_TOKEN_REMOVED权限:[public_profile]}],但AccessToken.getCurrentAccessToken()。getToken()返回有效令牌字符串,即使用户不再登录或已撤消对应用程序的授权也是如此。
Lisitso 2015年

@Lisitso您现在知道解决方案吗?
Jaec

1
@Jaec我使用了“ Aniket Thakur”提供的解决方案。您可以在这里找到其他地方。干杯!
Lisitso

27

这是允许我以编程方式从Facebook注销的代码段。如果您有任何需要改进的地方,请告诉我。

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

什么是jpotter6 mApp?
Amitsharma 2014年

任何Android应用程序中都可用的Application类的实例
Eenvincible

13

从Facebook的Android SDK v4.0开始,您需要执行以下操作:

LoginManager.getInstance().logOut();

这还不够。这将仅清除缓存的访问令牌和配置文件,以便AccessToken.getCurrentAccessToken()Profile.getCurrentProfile()现在将成为空。

要完全注销,您需要撤消权限,然后致电LoginManager.getInstance().logOut();。要撤销权限,请执行以下图形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();

2
这是对这个问题的正确答案。LoginManager.getInstance().logOut();仅清除本地缓存,而GraphRequest调用以编程方式撤消了用户Facebook帐户中的应用访问权限。两者都是必要的。一个人也不够。
2015年

我们必须在哪里放置此代码以获取删除权限?!在我的情况下,代码不起作用!您能提供完整的代码片段先生吗?!
Akshay Shinde

该代码有效,但发出警告:没有访问令牌的请求缺少应用程序ID或客户端令牌。我需要在上面的代码中为“ / {user-id} / permissions /”添加一些内容吗?
zeeshan

@zeeshan用我替换{user-id}
Amritpal singh '18

8

会话类已在SDK 4.0上删除。登录过程是通过类LoginManager完成的。所以:

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

正如参考升级到SDK 4.0所述

已删除会话-AccessToken,LoginManager和CallbackManager类将取代并替换Session类中的功能。


1
zeuter的答案更短,指出了相同的api调用。为什么重复?
8/14

3

是的,正如@luizfelippe所提到的,自SDK 4.0起,Session类已被删除我们需要使用LoginManager。

我只是看着LoginButton类进行注销。他们正在做这种检查。仅当accessToken不为null时,它们才会注销。因此,我认为最好将此代码也包含在我们的代码中。

AccessToken accessToken = AccessToken.getCurrentAccessToken();
if(accessToken != null){
    LoginManager.getInstance().logOut();
}

zeuter的答案更短,指出了相同的api调用。为什么重复?
8/14

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

0

Facebook提供了两种登录和注销帐户的方法。一种是使用LoginButton,另一种是使用LoginManager。LoginButton只是一个单击即可完成登录的按钮。另一方面,LoginManager自己执行此操作。在您的情况下,您已使用LoginManager自动注销。

LoginManager.getInstance().logout() 为您工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.