如何在不使用 Facebook 登录/注销按钮的情况下以编程方式从 Facebook SDK 3.0 注销?

Posted

技术标签:

【中文标题】如何在不使用 Facebook 登录/注销按钮的情况下以编程方式从 Facebook SDK 3.0 注销?【英文标题】:How to programmatically log out from Facebook SDK 3.0 without using Facebook login/logout button? 【发布时间】:2012-12-28 23:39:23 【问题描述】:

标题说明了一切。我正在使用自定义按钮来获取用户的 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 );
              
            );
    

理想情况下,我会在此方法开始时调用以注销所有以前的用户。

【问题讨论】:

【参考方案1】:

最新 SDK 更新:

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

LoginManager.getInstance().logOut();

原答案:

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

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

【讨论】:

您只需调用 Session.getActiveSession,如果它返回 null,那么您可以 1.) 使用 Session.Builder 创建一个新 Session,然后调用 Session.setActiveSession,或者 2.) 调用其中之一Session.openActiveSession 方法(静态方法,它为您打开和设置活动会话)。 你必须打开一个会话才能注销这一事实表明 Facebook SDK 的设计是多么糟糕……而不是提供带有标准回调的简单公共 API,你必须实现一个蹩脚的机制……太棒了。 Facebook SDK 和文档太可悲了! 官方 Facebook 文档包含示例中已弃用的代码 - 然后我们必须参考良好的旧堆栈才能取消弃用相同的代码。 而不是添加对对话没有贡献的 cmets,您应该给出缺少文档的具体示例(与问题/答案有关),或者您可以转到特定文档的底部页面,然后单击“此文档是否有帮助?”的“否”按钮。【参考方案2】:

此方法将帮助您在 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

    


【讨论】:

对我来说,在使用片段而不是活动的情况下,这是唯一可行的解​​决方案! 为什么代码中有 else 部分?如果用户没有登录,为什么需要重新登录然后退出? 出现错误 java.lang.NullPointerException:参数 'applicationId' 不能为空 我认为初始化会话的适当方法是 new Session.Builder(context).build();【参考方案3】:

由于 Facebook 的 Android SDK v4.0(参见changelog),您需要执行以下操作:

LoginManager.getInstance().logOut();

【讨论】:

谢谢,但我没有看到这实际上清除了会话。 LoginManager.logout() 只是在内部调用“AccessToken.setCurrentAccessToken(null); Profile.setCurrentProfile(null);”。我看到用户仍然可以登录,而无需在下次启动应用程序时重新输入凭据。你如何强制用户重新输入他们的凭据? 这个方法对我有帮助。在调用它并尝试重新登录后,出现了一个输入凭据屏幕,正如预期的那样。非常感谢。 正如@swooby 指出的那样,不幸的是,此解决方案不适用于使用 facebook sdk v4.x 的应用程序注销后,AccessToken 为 [AccessToken token:ACCESS_TOKEN_REMOVED permissions:[public_profile]] 但 AccessToken.getCurrentAccessToken( ).getToken() 即使用户不再登录或撤销对应用程序的授权,也会返回有效的令牌字符串。 @Lisitso 你现在知道解决方案了吗? @Jaec 我使用了“Aniket Thakur”提供的解决方案。您可以在这里找到其他响应。干杯!【参考方案4】:

这是允许我以编程方式从 facebook 注销的 sn-p。如果您发现任何我可能需要改进的地方,请告诉我。

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? 在任何 Android 应用程序中都可用的 Application 类的实例【参考方案5】:

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

【讨论】:

这是这个问题的正确答案。 LoginManager.getInstance().logOut(); 仅清除本地缓存,而 GraphRequest 调用以编程方式撤销用户 Facebook 帐户的应用程序访问权限。 两者都是必要的。单独一个都不够。 我们必须将此代码放在哪里以获得删除权限?!代码在我的情况下不起作用!能提供完整的代码sn-p先生吗!? 代码正在运行但发出警告:没有访问令牌的请求缺少应用程序 ID 或客户端令牌。我需要在上面的代码中添加一些东西到“/user-id/permissions/”吗? @zeeshan 用我替换 user-id【参考方案6】:

Session 类已在 SDK 4.0 中移除。登录管理是通过 LoginManager 类完成的。所以:

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

正如参考Upgrading to SDK 4.0 所说:

Session Removed - AccessToken、LoginManager 和 CallbackManager 类取代和替换 Session 类中的功能。

【讨论】:

zeuter 的答案更短,并指出相同的 api 调用。为什么要重复?【参考方案7】:

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

我刚刚查看了 LoginButton 类以进行注销。他们正在做这种检查。他们仅在 accessToken 不为空时注销。所以,我认为在我们的代码中也有这个更好..

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

【讨论】:

zeuter 的答案更短,并指出相同的 api 调用。为什么要重复?【参考方案8】:
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();    


【讨论】:

【参考方案9】:

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

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

【讨论】:

以上是关于如何在不使用 Facebook 登录/注销按钮的情况下以编程方式从 Facebook SDK 3.0 注销?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableViewCell 中快速创建 facebook 注销按钮

我们可以以编程方式注销 facebook

Facebook登录按钮不刷新自动注销

ios Facebook 登录按钮 - 不会更改为注销

facebook iOS sdk的登录注销问题

如何使用 Facebook SDK 在我的应用程序中注销 Facebook