如何在不使用 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 注销?的主要内容,如果未能解决你的问题,请参考以下文章