如何在应用程序启动时获取当前的 Facebook 访问令牌?

How to get current Facebook access token on app start?

在应用程序启动时,我需要知道用户是否登录以显示登录页面。

我的第一次尝试是调用 AccessToken.getCurrentAccessToken(),但这不起作用,请参阅

我的第二次尝试是使用 AccessTokenTracker,但这也不起作用。要使用 AccessTokenTracker,我必须先初始化 Facebook SDK。但是在这个初始化过程中,访问令牌被发送到跟踪器。此时未创建跟踪器,无法接收令牌。

我的第三次尝试是创建我自己的 AccessTokenTracker,它看起来像原来的那样。我在初始化 SDK 之前创建并注册了它。现在我的跟踪器在这个 SDK 初始化过程中获得了令牌。

有了这些知识,我打开了一个 bug report at Facebook 问题:

来自 Facebook 的回答:

This doesn't look like bug. The AccessTokenTracker ::onCurrentAccessTokenChanged should let you know when the class has received a token.

我知道这是行不通的。现在我知道没有错误了。

但是我的问题怎么解决呢?

这行不通:

FacebookSdk.sdkInitialize(getApplicationContext());
mAccessTokenTracker = new AccessTokenTracker() {

    @Override
    protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {

        Timber.i("AccessTokenTracker oldAccessToken: " + oldAccessToken + " - currentAccessToken: " + currentAccessToken);
    }
};

一定是这样(这个Facebook v4.1.2)

FacebookSdk.sdkInitialize(getApplicationContext());

mFacebookCallbackManager = CallbackManager.Factory.create();

mFacebookAccessTokenTracker = new AccessTokenTracker() {
    @Override
    protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
        ...
    }
};

mFacebookLoginButton = new LoginButton(this);
mFacebookLoginButton.setReadPermissions(Arrays.asList("public_profile", "email", "user_birthday"));
mFacebookLoginButton.registerCallback(mFacebookCallbackManager, new FacebookCallback<LoginResult>() {
    @Override
    public void onSuccess(LoginResult loginResult) {
        ...
        String token = loginResult.getAccessToken().getToken()
        ...
    }

    @Override
    public void onCancel() {
        Lo.d("Facebook login - the user did not give permission");
    }

    @Override
    public void onError(FacebookException e) {
        e.printStackTrace();
    }
});

你说的需要先初始化SDK。然后创建访问令牌跟踪器,然后通过 AccessToken.getCurrentAccessToken().

检查当前访问令牌

如果 SDK 初始化程序足够快,可以在您创建跟踪器之前设置令牌,那么您对 ​​currentAccessToken 的调用将获得令牌。如果 sdk 初始化比跟踪器注册慢,那么跟踪器将获得访问令牌。

如果您已登录,那么您可以写 AccessToken.getCurrentAccessToken(); 获取您当前的访问令牌

如果您已登录,那么您可以写:AccessToken.getCurrentAccessToken();获取您当前的访问令牌

@Gokhan Caglar 是对的,如果 Facebook Sdk 未完成初始化,则访问令牌为空。那么这个呢?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookSdk.sdkInitialize(this /* applicationContext */);
    setContentView(R.layout.activity_getting_started);

    callbackManager = CallbackManager.Factory.create();

    if (AccessToken.getCurrentAccessToken() == null) {
        waitForFacebookSdk();
    } else {
        init();
    }
}

private void waitForFacebookSdk() {
    AsyncTask asyncTask = new AsyncTask() {
        @Override
        protected Object doInBackground(Object[] params) {
            int tries = 0;
            while (tries < 3) {
                if (AccessToken.getCurrentAccessToken() == null) {
                    tries++;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    return null;
                }
            }
            return null;
        }

        @Override
        protected void onPostExecute(Object result) {
            init();
        }
    };
    asyncTask.execute();
}

private void init() {
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    if (accessToken == null || accessToken.isExpired()) {
        // do work
    } else {
        // do some other work
    }
}

在我看来这不是最好的解决方案,但等待 Facebook Sdk 可能会有所帮助。

在 Intializer.java 应用程序中初始化 Facebook SDK,以便 activity 中的任何代码都将在初始化后执行。将您的初始化程序添加到清单文件