Android Facebook SDK:检查用户是否已登录

34

我在我的Android应用程序中有一个功能,用户授权该应用程序并共享链接。

我还需要为用户提供注销Facebook的选项,并且如果用户未登录(或未授权该应用程序),则需要有条件地禁用此按钮。

我似乎找不到在Android SDK上调用API以让FB查询用户是否已登录的方法。

我找到的是 getAccessExpires():

检索当前会话的过期时间(自Unix纪元以来的毫秒数),如果会话不过期或不存在,则为0。

检查会话是否等于0是正确的方式吗?还是我遗漏了什么?


1
你看过这个文档吗 - https://developers.facebook.com/docs/reference/androidsdk/authentication/? - deesarus
10个回答

54

Facebook SDK 4.x 版本现在有不同的方法:

boolean loggedIn = AccessToken.getCurrentAccessToken() != null;

或者

通过使用函数

boolean loggedIn;
//...
loggedIn = isFacebookLoggedIn();
//...
public boolean isFacebookLoggedIn(){
    return AccessToken.getCurrentAccessToken() != null;
}

查看此链接以获得更好的参考 https://developers.facebook.com/docs/facebook-login/android 请注意标题 "Access Tokens and Profiles",它说"您可以通过检查AccessToken.getCurrentAccessToken()和Profile.getCurrentProfile()来查看某人是否已登录"


1
它总是在不断变化,让我们看看下一步会是什么。 - Shajeel Afzal
4
我投了一票,但显然,在重新启动应用程序后,getCurrentAccessToken()仍然返回空值,同时查看登录按钮:它显示为“退出登录”。我们在这里错过了什么? - CularBytes
@RageCompex:嗯,它不应该返回null,我从未遇到过这种情况,也许你应该在developers.facebook.com的应用程序设置中启用“单点登录”和“深度链接”,这样你就不必一次又一次地登录了。此外,请检查来自Facebook Android SDK的登录指南中的代码。 - Diljeet
@lacas 请查看以下链接以获得更好的参考: https://developers.facebook.com/docs/facebook-login/android/v2.3 如果您遗漏了某些内容,请查看此处,还要检查一下这个标题:“访问令牌和个人资料”,它说:“您可以通过检查AccessToken.getCurrentAccessToken()和Profile.getCurrentProfile()来查看一个人是否已经登录”。 - Diljeet
1
@Diljeet 我重新检查并确认了我之前所说的,即使关闭我的应用程序并清除 RAM,当调用时它会导致访问令牌为空,你必须在再次启动/稍后启动应用程序时刷新访问令牌。谢谢。 - Ashraf Alshahawy
显示剩余5条评论

48

我在FB文档中费了好大劲才找到一个简单的答案。使用Facebook SDK版本3.0,我认为有两种方法可以检查用户是否已登录。

1)使用 Session.isOpened()

要使用此方法,您需要使用getActiveSession()检索活动会话,然后(这是令人困惑的部分)判断会话是否处于用户已登录或未登录状态。我认为对于已登录的用户,唯一重要的事情就是会话是否isOpened()。因此,如果会话不是null并且处于打开状态,则用户已登录。在所有其他情况下,用户已注销(请记住Session可能具有除打开和关闭以外的其他状态)。

public boolean isLoggedIn() {
    Session session = Session.getActiveSession();
    return (session != null && session.isOpened());
}

这个函数还有另一种编写方式,详见此答案,但我不确定哪种方式更清晰或者符合“最佳实践”。

2) 使用 Session.StatusCallbackUiLifecycleHelper 来不断监测状态变化

如果您遵循这个教程,则会设置 UiLifecycleHelper 并在实例化时向其注册一个 Session.StatusCallback 对象。有一个回调方法 call(),您可以在 Session.StatusCallback 中重写它,据说每次用户登录/注销时都会调用该方法。在该方法中,您可以跟踪用户是否已登录。可能会像这样:

private boolean isLoggedIn = false; // by default assume not logged in

private Session.StatusCallback callback = new Session.StatusCallback() {
    @Override
    public void call(Session session, SessionState state, Exception exception) {
        if (state.isOpened()) { //note: I think session.isOpened() is the same
            isLoggedIn = true;
        } else if (state.isClosed()) {
            isLoggedIn = false;
        }
    }
};

public boolean isLoggedIn() {
    return isLoggedIn;
}

我认为方法1更简单,可能是更好的选择。

顺便提一句,有没有人能够解释一下为什么教程喜欢调用state.isOpened()而不是session.isOpened()呢?因为两者似乎是可以互换的(session.isOpened()似乎只是调用了state版本)。


在什么情况下会使用openActiveSessionFromCache函数? - Madhur Ahuja
@MadhurAhuja 我不是很确定。我没有太多地玩过FB SDK,因为我只需要它的登录功能。 - Tony Chan
我已经阅读并使用了第一个选项的代码,其中包含session.IsOpened()。现在我遇到了一个问题。如果用户通过设备浏览器登录Facebook,则此方法有效。但是,如果用户通过Facebook应用程序登录,则会话始终为空。有解决这个问题的想法吗?这是我的问题链接http://stackoverflow.com/questions/22407482/facebook-login-via-app-vs-via-device-browser-in-android-app - Luke Villanueva
只是挑剔一下,为什么不直接写成 return session != null && session.isOpened()isLoggedIn = state.isOpened() 呢? - mr5
@mr5 好建议。我编辑了答案以简化代码。我之前没有其他原因,只是当时容易跟随逻辑。但我喜欢你的建议,更有效率。至于第二种方法/建议,我会保留它作为我的原始答案,只是因为SessionState可以有其他状态而不仅仅是openclosed,我还没有深入研究,所以我只想在明确打开/关闭时才改变isLoggedIn。如果有人能确认其他状态意味着用户已注销,则我会很乐意更改答案。 - Tony Chan
我正在使用3.23.0版本。尽管用户先前已登录,但在检查闪屏时,Session.getActiveSession()始终返回null。为什么? - Prashanth Debbadwar

6

读者注意:这在新的FB 3.0 SDK中已被弃用。

facebook.isSessionValid()如果用户已登录则返回true,否则返回false。


2
读者注意:这在新的FB 3.0 SDK中已被弃用。@Jesse,我相信检查已登录用户的正确方法是在我的答案中吗? - Tony Chan
在什么情况下会使用openActiveSessionFromCache函数? - Madhur Ahuja
是的,这个函数不起作用,新的函数怎么使用? - Nitesh Verma

3

使用Android Studio:

compile 'com.facebook.android:facebook-android-sdk:4.0.1'

然后像这样检查登录:

private void facebookPost() {
    //check login
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    if (accessToken == null) {
        Log.d(TAG, ">>>" + "Signed Out");
    } else {
        Log.d(TAG, ">>>" + "Signed In");
    }
}

3
Session.getActiveSession().isOpened()

如果用户已登录,则返回 true,否则返回 false。


4
当没有活动会话存在时抛出NPE异常。 - Guy
1
你应该首先使用 if 语句来检查会话是否为 null(如果是,则通常将其视为已关闭)。 - LoneDuck

2

1
对于Facebook Android SDK 4.x,您需要使用“AccessToken.getCurrentAccessToken()”,正如@Diljeet所说,但他的检查对我不起作用,我最终通过执行以下操作进行了检查:
活动“onCreate”:
facebookAccessToken = AccessToken.getCurrentAccessToken();

要检查会话是否仍处于活动状态(我在“onResume”方法中进行了操作,但您可以在需要的任何位置执行):

  if(facebookAccessToken != null){
        sessionExpired = facebookAccessToken.isExpired();
  }else{
        sessionExpired = true;
  }

更多信息请参见https://developers.facebook.com/docs/facebook-login/android


0

我遇到了同样的问题。这是我使用 SDK 4.0 的解决方案:

首先,在处理登录检查的活动中,请确保首先调用以下 primary 方法:

        FacebookSdk.sdkInitialize(this.getApplicationContext());

在你的 onCreate 方法中加入以下代码:
updateWithToken(AccessToken.getCurrentAccessToken());

    new AccessTokenTracker() {
        @Override
        protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) {
            updateWithToken(newAccessToken, handler);
        }
    };

然后添加名为的方法:

private void updateWithToken(AccessToken currentAccessToken) {
    if (currentAccessToken != null) {
        fillUIWithFacebookInfos(handler);
    } else {
        login();
    }
}

这种方式将处理已经登录的用户和新登录的用户。


0

使用新的SDK似乎运行得非常顺利。

private boolean isFacebookLoggedIn(){
    Session session = Session.getActiveSession();

    if (session != null) {
        //Session can be open, check for valid token
        if (!session.isClosed()) {
            if(!session.getAccessToken().equalsIgnoreCase("")){
                return true;
            }
        }
    }
    return false;
}

0

我只是用FB SDK做登陆功能.. Facebook开发者拒绝了我的应用,因为每当用户登录时,我就发送注销指令..我不关心用户的个人资料..我只是用FB做登陆.. FB告诉我如果用户登陆了就不要发送注销指令.

我找到了一种“黑客”方式... 现在,无论用户用Google、Facebook还是普通账号登陆,我的应用都不会发送注销指令..当他们点击注销时,在这三种情况下,我使用 LoginManager.getInstance().logOut();

无论他们使用哪个平台...都没有崩溃 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接