Profile.getCurrentProfile() возвращает null после входа в систему (FB API v4.0)
По какой-то причине Profile.getCurrentProfile()
отображается сразу по ошибке сразу после входа в FaceBook, используя FB API версии 4.0.
Это вызывает проблемы для меня в моем приложении, потому что я не могу отображать следующий Activity
с Profile
равным нулю.
Причина, по которой я говорю, что это ошибка, иногда возникает из-за того, что если я закрываю приложение и снова его открываю, я могу перейти к следующему Activity
, но если я еще не зарегистрирован, а затем login, Profile
имеет значение null. Кажется, это на короткий период.
Есть ли работа или исправление?
Ответы
Ответ 1
Как Hardy сказал, вам нужно создать экземпляр 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 только для вызова mProfileTracker.startTracking();
, если Profile.getCurrentProfile()
возвращает null.
Ответ 2
Следуя суфийскому ответу, вы также можете сохранить новый профиль в классе 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();
}
Ответ 3
Facebook загружает информацию профиля асинхронно, поэтому даже после получения результата от обратного вызова login, 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();
}
}
Ключевым моментом здесь является то, что вы не должны вызывать Profile.getcurrentprofile из обратного вызова входа (либо LoginManager, registercallback, либо loginButton.registercallback) - значения ненадежны. Настройте трекер и полагайтесь на его стрельбу в подходящее время, чтобы получить обновленную информацию о профиле.