3

Я работаю с Facebook SDK 4.0 и используя встроенный LoginButton. У меня есть Fragment, который содержит LoginButton и еще один, который содержит только TextBox.Facebook Access Token lost after App Restart

Вот фрагмент кода из Fragment:

public class LoginFragment extends Fragment { 

private OnLoginFragmentInteractionListener mListener; 
LoginButton loginButton; 
CallbackManager callbackManager; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
    } 

    callbackManager = CallbackManager.Factory.create(); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_login, container, false); 

    loginButton = (LoginButton) view.findViewById(R.id.login_button); 

    // If using in a fragment 
    loginButton.setFragment(this); 

    // Callback registration 
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() { 
     @Override 
     public void onSuccess(LoginResult loginResult) { 
      Toast.makeText(getActivity(), "Logged in successfully.", Toast.LENGTH_SHORT).show(); 
      onLoginEvent(true); 
     } 
     @Override 
     public void onCancel() { 
      Toast.makeText(getActivity(), "Login canceled.", Toast.LENGTH_SHORT).show(); 
      onLoginEvent(false); 
     } 
     @Override 
     public void onError(FacebookException exception) { 
      Toast.makeText(getActivity(), "Failed to log in. Please try again.", Toast.LENGTH_SHORT).show(); 
      onLoginEvent(false); 
     } 
    }); 

    return view; 
} 

public void onLoginEvent(boolean loginSuccess) { 
    if (mListener != null) { 
     mListener.onLoginFragmentInteraction(loginSuccess); 
    } 
} 

public interface OnLoginFragmentInteractionListener { 
    public void onLoginFragmentInteraction(boolean onLoginSuccess); 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    callbackManager.onActivityResult(requestCode, resultCode, data); 
} 
} 

Деятельность выглядит примерно так:.

public class LoginActivity extends ActionBarActivity implements 
    LoginFragment.OnLoginFragmentInteractionListener, TestFragment.OnFragmentInteractionListener { 

static final String TAG = "LoginActivity"; 

private LoginFragment loginFragment; 
private TestFragment testFragment; 
private AccessToken accessToken; 
private AccessTokenTracker accessTokenTracker; 
private Profile fbProfile; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_login); 

    FacebookSdk.sdkInitialize(getApplicationContext()); 

    if (savedInstanceState == null) { 
     // Add the fragment on initial activity setup 
     Log.d(TAG, "Bundle = null, isLoggedIn() = " + isLoggedIn()); 
     if (isLoggedIn()) { 
      testFragment = new TestFragment(); 
      getSupportFragmentManager().beginTransaction() 
        .add(R.id.fragment_container, testFragment).commit(); 
     } else { 
      loginFragment = new LoginFragment(); 
      getSupportFragmentManager().beginTransaction() 
        .add(R.id.fragment_container, loginFragment).commit(); 
     } 
    } else { 
     // Or set the fragment from restored state info 
     Fragment frag = getSupportFragmentManager() 
       .findFragmentById(R.id.fragment_container); 
     if (frag instanceof LoginFragment) { 
      Log.d(TAG, "Bundle != null, fragment = LoginFragment"); 
      loginFragment = (LoginFragment) frag; 
     } 
     else if (frag instanceof TestFragment) { 
      Log.d(TAG, "Bundle != null, fragment = TestFragment"); 
      testFragment = (TestFragment) frag; 
     } 
    } 
} 


@Override 
public void onLoginFragmentInteraction(boolean loginSuccess) { 
    updateUI(loginSuccess); 
} 

public void updateUI(boolean loggedIn) { 
    // User is logged in, show the main fragment 
    if (loggedIn) { 
     testFragment = new TestFragment(); 
     getSupportFragmentManager().beginTransaction() 
       .replace(R.id.fragment_container, testFragment).commit(); 
    } 
    // User is logged out, show the login fragment 
    else { 
     loginFragment = new LoginFragment(); 
     getSupportFragmentManager().beginTransaction() 
       .replace(R.id.fragment_container, loginFragment).commit(); 
    } 
} 

public boolean isLoggedIn() { 
    accessToken = AccessToken.getCurrentAccessToken(); 
    if (accessToken != null && !accessToken.isExpired()) 
     return true; 
    else 
     return false; 
} 
} 

То, что я хочу сделать, это проверить, если пользователь уже вошел в систему Если у них есть, то я показываю тестовый фрагмент, иначе я покажу фрагмент входа.

Поэтому, когда пользователь впервые входит в систему, я использую обратный вызов интерфейса, чтобы уведомить о том, что пользователь вошел в систему и отобразил тестовый фрагмент. Кроме того, если пользователь уходит из приложения и затем возвращается, я проверяю метод onCreate(), если пользователь выполнил вход в систему, проверив токен доступа.

Когда пользователь впервые входит в систему, он работает по своему желанию. Но проблема, с которой я столкнулся, заключается в том, что если я убью приложение или удалю его из списка «Аванты», я потеряю токен доступа. AccessToken.getCurrentAccessToken() всегда возвращает null. Разве это не правильный способ справиться с этим?

ответ

2

Как вы упомянули в своем комментарии. При завершении инициализации FacebookSDK вы должны проверить пользователя во время входа в систему.
Проблема в вашем случае заключается в том, что вы проверили AccessToken, когда SDK еще не завершил инициализацию. Чтобы решить эту проблему, проверьте AcessToken на onInitialized() метод FacebookSdk.InitializeCallback, который вызывается при инициализации SDK.

FacebookSdk.sdkInitialize(getApplicationContext(), new FacebookSdk.InitializeCallback() { 
    @Override 
    public void onInitialized() { 
     if (isLoggedIn()) { 
      .............. 
     } 
    } 
});
+0

Пожалуйста, постарайтесь ответить на весь вопрос. Что насчет «Но проблема, с которой я сталкиваюсь, заключается в том, что если я убью приложение или удалю его из списка« Актеры », я потеряю токен доступа». ? – 0X0nosugar

+0

Я протестировал и даже перезапустил эмулятор, и этот код действительно сработал. Вы попробовали это? –

+0

Я думаю, хорошо, что вы протестировали свое решение. Гораздо лучше, чем «попробовать этот» сорт :) Сказав это, я вижу, что вы ввели обратный вызов там, где раньше не было. Моя проблема остается: ссылка от user2558050 больше похожа на исходный «проблемный код» (без обратного вызова), поэтому, если вы могли бы объяснить свое решение в дополнение к публикации фрагмента кода, тогда такие люди, как я (никогда ничего не делал с SDK в facebook) лучше поймут, почему они могут сделать это по-своему. – 0X0nosugar

0

Когда логин успешно сохраняет токен доступа. В базу данных или общие настройки. Когда ваше приложение начнет проверку, есть ли токен доступа, и если он действителен.

+1

Согласно официальной документации: «FacebookSDK сохраняет эти данные в общих настройках и устанавливает его во время инициализации SDK Вы можете увидеть, если человек уже вошел в систему с помощью проверки AccessToken.getCurrentAccessToken()..» https://developers.facebook.com/docs/facebook-login/android/v2.3#access_profile Не следует ли обрабатывать его автоматически? – akshayt23