Profile.getCurrentProfile()在登录后返回null(FB API v4.0)

时间:2015-04-15 06:12:30

标签: android facebook

出于某种原因,Profile.getCurrentProfile()在使用FB API v4.0登录FaceBook后立即显示null。

这在我的应用中导致了我的问题,因为我无法显示我的下一个Activity Profile为空。

我之所以说它为空,有时是因为如果我关闭我的应用并重新打开它,我就可以进入下一个Activity,但如果我&# 39; m尚未登录,然后登录,Profile为空。这似乎是短暂的。

是否有解决方法或解决此问题?

4 个答案:

答案 0 :(得分:82)

Hardy said一样,您必须创建ProfileTracker的实例,该实例将开始跟踪个人资料更新,(即,当用户的个人资料完成提取时,将调用ProfileTracker.onCurrentProfileChanged() )。

以下是您登录FB并获取用户个人资料所需的完整代码:

LoginButton loginButton = (LoginButton) findViewById(R.id.btn_facebook);
loginButton.setReadPermissions("public_profile");
mCallbackManager = CallbackManager.Factory.create();
loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {

    private ProfileTracker mProfileTracker;

    @Override
    public void onSuccess(LoginResult loginResult) {
        if(Profile.getCurrentProfile() == null) {
            mProfileTracker = new ProfileTracker() {
                @Override
                protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
                    Log.v("facebook - profile", currentProfile.getFirstName());
                    mProfileTracker.stopTracking();
                }
            };
            // no need to call startTracking() on mProfileTracker
            // because it is called by its constructor, internally.
        }
        else {
            Profile profile = Profile.getCurrentProfile();
            Log.v("facebook - profile", profile.getFirstName());
        }
    }

    @Override
    public void onCancel() {
        Log.v("facebook - onCancel", "cancelled");
    }

    @Override
    public void onError(FacebookException e) {
        Log.v("facebook - onError", e.getMessage());
    }
});

您必须覆盖您的活动或片段onActivityResult(),如下所示:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // if you don't add following block,
    // your registered `FacebookCallback` won't be called
    if (mCallbackManager.onActivityResult(requestCode, resultCode, data)) {
        return;
    }
}

编辑:

使用Alex Zezekalo's suggestion更新代码,仅在mProfileTracker.startTracking();返回null时才调用Profile.getCurrentProfile()

答案 1 :(得分:18)

根据Sufian的回答,您还可以将新配置文件保存到Profile类:

@Override
public void onSuccess(LoginResult loginResult) {
    ProfileTracker profileTracker = new ProfileTracker() {
        @Override
        protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
            this.stopTracking();
            Profile.setCurrentProfile(currentProfile);

        }
    };
    profileTracker.startTracking();
}

答案 2 :(得分:4)

Facebook以异步方式加载配置文件信息,因此即使从登录回调中获取结果,Profile.getCurrentProfile()也将返回null。

但是,每次用户通过Facebook登录时(第一次和每次后续),他的个人资料都会发生变化,并会触发个人资料跟踪器。这是您必须调用个人资料的地方。

以下是构建代码的方法。您必须监听要更新的ProfileTracker以更新您的用户属性 - 避免在登录过程中在跟踪器外调用getCurrentProfile:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
        callbackManager = CallbackManager.Factory.create();
        profileTracker = new ProfileTracker() {
            @Override
            protected void onCurrentProfileChanged(Profile profile, Profile profile1) {


 //Listen for changes to the profile or for a new profile: update your
 //user data, and launch the main activity afterwards. If my user has just logged in,
 //I make sure to update his information before launching the main Activity.

                Log.i("FB Profile Changed", profile1.getId());
                updateUserAndLaunch(LoginActivity.this);


            }
        };
        profileTracker.startTracking();

        accessTokenTracker = new AccessTokenTracker() {
            @Override
            protected void onCurrentAccessTokenChanged(
                    AccessToken oldAccessToken,
                    AccessToken currentAccessToken) {




//Check that the new token is valid. This tracker is fired
//when the user logs in the first time and afterwards any time he interacts with 
//the Facebook API and there is a change in his permissions.

                if (!accessTokenIsValid(currentAccessToken)){
                    Log.i("FB Token Updated", String.valueOf(currentAccessToken.getPermissions()));
                    requestLogin();

                }
            }
        };
        // User already has a valid access token? Then take the user to the main activity
        if (accessTokenIsValid(AccessToken.getCurrentAccessToken())){
               launchApp();
        }else{
//Show the Facebook login page
            requestLogin();
        }

    }

这里的关键是你不应该从登录回调(LoginManager,registercallback或loginButton.registercallback)调用Profile.getcurrentprofile - 值不可靠。设置跟踪器并依靠它在适当的时间触发,以获得更新的配置文件信息。

答案 3 :(得分:1)

我有一个比其他答案更简单的建议。

无需注册登录回调:

registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() { ... }

相反,只要您需要用户数据(例如点击按钮),就可以开始跟踪配置文件更改:

new ProfileTracker() {
    @Override
    protected void onCurrentProfileChanged(Profile oldProfile, Profile profile) {
        stopTracking();

        Log.d(TAG, profile.getFirstName());
        Log.d(TAG, profile.getLastName());
        Log.d(TAG, String.format("https://graph.facebook.com/%s/picture?type=large", profile.getId()));
    }
}.startTracking();

然后通过以下方式启动Facebook登录流程:

LoginManager.getInstance().logInWithReadPermissions(getContext(), Arrays.asList("public_profile"));

要使上述代码正常工作,您当然需要在Activity中准备常用的东西:

private CallbackManager mCallbackManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mCallbackManager = CallbackManager.Factory.create();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (FacebookSdk.isFacebookRequestCode(requestCode) &&
            mCallbackManager.onActivityResult(requestCode, resultCode, data)) {
        // do nothing
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

另外,请不要忘记修改AndroidManifest.xml文件。