出于某种原因,Profile.getCurrentProfile()
在使用FB API v4.0登录FaceBook后立即显示null。
这在我的应用中导致了我的问题,因为我无法显示我的下一个Activity
Profile
为空。
我之所以说它为空,有时是因为如果我关闭我的应用并重新打开它,我就可以进入下一个Activity
,但如果我&# 39; m尚未登录,然后登录,Profile
为空。这似乎是短暂的。
是否有解决方法或解决此问题?
答案 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文件。